2

当我在调试模式下运行使用以下代码创建的 .exe 时,它​​显示一些断言失败并且程序崩溃但是当我运行从以下代码的发布模式创建的相同 exe 时,它​​工作正常。

请帮助确定为什么我在调试模式下出现断言失败,但在发布模式下却没有。

#include<iostream>
using namespace std;
#include<string.h>

void main()
{
    char *buf  = new char[5];   //pre-allocated buffer
    buf = "Hello";
    delete [] buf;
    getchar();
    //cout<<buf;
    //string *p = new (buf) string("hi");  //placement new
    //string *q = new string("hi");  //ordinary heap allocation
}
4

6 回答 6

4
  1. void main是错的。main返回int。没有例外。
  2. 你在做delete[] "Hello""Hello"是字符串文字;你不能delete
于 2012-11-29T13:34:52.587 回答
4
 char *buf  = new char[5];   //pre-allocated buffer

在这里,您定义一个指针,并将其初始化为指向一个动态分配的缓冲区,其中有 5 个字符的空间。

buf = "Hello";

在这里,您将指针初始化为指向字符串文字的开头。

 delete [] buf;

在这里,您删除 [] buf 指针,但 buf 指针不再指向您新建 [] 的任何内容,它指向字符串文字。您只能删除/删除 [] 指向您从 new/new[] 获得的内容的指针。所以你会得到未定义的行为,并且可能会崩溃

您可能打算将字符串的内容复制到您 new[]'d 的缓冲区中。请记住考虑 nul 终止符:

int main()
{
    char *buf  = new char[6];   //pre-allocated buffer
    strcpy(buf, "Hello");
    delete [] buf;
    getchar();
    //cout<<buf;
    //string *p = new (buf) string("hi");  //placement new
    //string *q = new string("hi");  //ordinary heap allocation
}

虽然,在 C++ 中,你宁愿使用 std::string from #include <string>;

std::string = "Hello";
于 2012-11-29T13:35:06.293 回答
2

您正在尝试解除分配字符串文字"Hello"。这一行:

buf = "Hello";

将指针 重定向buf到字面量"Hello"。您可能打算这样做:

char *buf = new char[6]; //need one extra space for terminating NUL character
strcpy(buf, "Hello");
于 2012-11-29T13:36:47.733 回答
2

当你这样做时:

buf = "Hello";

您基本上是在更改指向buf只读内存区域的指针值(内存地址),因为"Hello"它是字符串文字,因此存储在只读内存中。

然后您尝试释放该内存,从而导致崩溃。

此外,"Hello"是 6 字节长,而不是 5。

于 2012-11-29T13:34:45.597 回答
2

因为未定义的行为意味着任何事情都可能发生。问题是buf = "Hello"将字符串文字的地址分配给buf,然后尝试删除该文字。在调试模式下编译时,检查代码看到地址不能被删除;在发布模式下,检查没有完成,删除只是踩在不重要的东西上。

于 2012-11-29T13:35:50.070 回答
2
 char *buf  = new char[6];   //pre-allocated buffer
 strncpy(buf, "hello", 6);
 delete [] buf;

buf = "你好"; 将改变 buf 的值,从指向 new char[6] 的指针变为指向“hello”的指针,即不在堆中的内存块。

于 2012-11-29T13:35:33.220 回答