我假设 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 只要有可能。

游戏的名称是“只摧毁你创造的东西”。以下是这些对:

  1. malloc/free
  2. calloc/free
  3. new/delete
  4. 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[]. 。所以你应该尽可能释放它。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top