是否需要销毁 char * = “string” 或 char * = new char[6]?
题
我假设 char* = "string"
是一样的 char* = new char[6]
. 。我相信这些字符串是在堆而不是堆栈上创建的。那么,当我使用完它们后,我是否需要销毁它们或释放它们的内存,或者它们会自行销毁吗?
解决方案
不。当您自己使用手动分配内存时,只需手动释放字符串 malloc
函数(C 语言)或 new
运算符(在 C++ 中)。如果你不使用 malloc
或者 new
, ,那么 char*
或字符串将在堆栈上创建或作为编译时常量创建。
其他提示
不。当你说:
const char* c = "Hello World!";
您将 c 分配给“预先存在的”字符串常量,该常量与以下内容不同:
char* c = new char[6];
仅在后一种情况下,您才在堆上分配内存。所以当你完成后你会调用delete。
我假设当我这样做时
char* = "string"
它与char* = new char[6]
.
不。第一个所做的是创建一个常量。修改它是未定义的行为。但回答你的问题;不,你不必摧毁它们。只是注意一下,始终使用 std::string
只要有可能。
游戏的名称是“只摧毁你创造的东西”。以下是这些对:
malloc
/free
calloc
/free
new
/delete
new []
/delete []
由于您使用创建了第二个字符串 new []
, ,你有责任摧毁它 delete []
. 。称呼 delete [] string2
当你完成时。
现在,如果您的代码足够复杂并且难以跟踪删除,请考虑使用作用域指针或自动指针。这 boost::scoped_ptr
boost 库中的类是一个很好的起点。还请查看 RAII 习语,非常方便且有用的东西。
他们不一样。您的第一个示例是一个常量字符串,因此它绝对不是从堆中分配的。第二个示例是 6 个字符的运行时内存分配,它来自堆。您不想删除第一个示例,但您需要 delete []
你的第二个例子。
您不知道字符串文字存储在哪里。它甚至可能是只读内存,因此您的代码应为:
const char* c = "string";
还有一个 新的 字符数组应该是 删除d 就像任何其他动态分配的内存区域一样。
new 始终是一个分配,而定义内联字符串实际上将数据嵌入到程序本身中并且无法更改(某些编译器通过巧妙的技巧允许这样做,不必打扰)。
某些编译器键入内联字符串,以便您无法修改缓冲区。
char* const sz1 = "string"; // embedded string, immutable buffer
char* sz2 = new char[10]; // allocated string, should be deleted
让我们看看 GCC 4.8 x86-64 Linux 做了什么
程序:
#include <cstdio>
int main() {
const char *s = "abc";
char *sn = new char[4];
sn[3] = '\0';
std::printf("%s\n", s);
std::printf("%s\n", sn);
}
编译和反编译:
g++ -ggdb -std=c++98 a.cpp
objdump -CSr a.o
输出包含:
const char *s = "abc";
8: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp)
f: 00
c: R_X86_64_32S .rodata
char *sn = new char[4];
10: bf 04 00 00 00 mov $0x4,%edi
15: e8 00 00 00 00 callq 1a <main+0x1a>
16: R_X86_64_PC32 operator new[](unsigned long)-0x4
1a: 48 89 45 f8 mov %rax,-0x8(%rbp)
解释:
char *s = "abc"
进入.rodata
. 。所以你不能free
以任何方式。char *sn = new char[4];
来自于输出operator new[]
. 。所以你应该尽可能释放它。