我认为char* = "string"
与char* = new char[6]
相同。我相信这些字符串是在堆而不是堆栈上创建的。所以当我使用它们或者它们被自己毁坏时,我是需要销毁它们还是释放它们的记忆?
答案 0 :(得分:31)
没有。当您使用malloc
函数(在C中)或new
运算符(在C ++中)手动分配内存时,您只需手动释放字符串。如果不使用malloc
或new
,则会在堆栈上创建char*
或字符串,或者作为编译时常量。
答案 1 :(得分:17)
没有。当你说:
const char* c = "Hello World!";
您将c分配给“预先存在的”字符串常量,该常量与以下内容不同:
char* c = new char[6];
仅在后一种情况下,您在堆上分配内存。所以,当你完成后,你会打电话给删除。
答案 2 :(得分:4)
我假设当我
char* = "string"
与char* = new char[6]
相同时。
没有。第一个做的是创建一个常量。修改它是未定义的行为。但要回答你的问题;不,你不必摧毁它们。只需注意,请尽可能使用std::string
。
答案 3 :(得分:4)
游戏的名称是“仅销毁您创建的内容”。以下是对:
malloc
/ free
calloc
/ free
new
/ delete
new []
/ delete []
由于您使用new []
创建了第二个字符串,因此您有责任使用delete []
销毁它。完成后请致电delete [] string2
。
现在,如果您的代码足够复杂并且难以跟踪删除,请考虑使用范围指针或自动指针。来自boost库的boost::scoped_ptr
类是一个很好的开始。还要研究RAII成语,非常方便和有用的东西。
答案 4 :(得分:3)
他们不一样。你的第一个例子是一个常量字符串,所以它绝对不是从堆中分配的。第二个例子是6个字符的运行时内存分配,它来自堆。您不想删除第一个示例,但需要delete []
第二个示例。
答案 5 :(得分:1)
您不知道字符串文字的存储位置。它甚至可能是只读内存,因此您的代码应为:
const char* c = "string";
new char数组应该 delete d,就像任何其他动态分配的内存区域一样。
答案 6 :(得分:0)
new始终是一个分配,而定义一个内联字符串实际上是将数据嵌入到程序本身中并且无法更改(某些编译器通过智能技巧允许这样做,不要打扰)。
某些编译器会输入内联字符串,以便您无法修改缓冲区。
char* const sz1 = "string"; // embedded string, immutable buffer
char* sz2 = new char[10]; // allocated string, should be deleted
答案 7 :(得分:0)
让我们看看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[]
的输出。所以你应该尽可能地释放它。