14

我有两个关于new[]和的代码块delete[]

1)

#include <string>

int main()
{
  std::string *p = new std::string[0];
  delete[] p;

  return 0;
}

2)在这种情况下,我只是std::string改为int

int main()
{
  int *p = new int[0];

  delete[] p;

  return 0;
}

我的问题是:

为什么第一个程序崩溃并显示以下消息(在 linux 环境中):

Segmentation fault (core dumped)

但是第二个程序运行良好没有任何错误?

编辑

编译器:g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2

我只是使用g++没有任何参数来编译它。

如果是编译器错误,它们是否应该按照标准崩溃?

4

1 回答 1

13

这应该是一个 gcc 错误。整个new[]表达式被忽略并p变得未初始化,然后我们delete[]一个未初始化的指针崩溃了。如果我们用它编译程序-Wall会警告你

警告:“p”在此函数中未初始化使用

这显然是错误的。该表达式new X[0]在 C++03 和 C++11(第 5.3.4/7 节)中定义良好,并且在 clang 中可以正常工作,因此唯一合乎逻辑的结论是它是一个 gcc 错误。


new[]仅当要构造的类型具有任何非平凡的构造函数时,才存在消除错误。并且段错误发生在类型具有析构函数,因为delete[]然后将需要取消引用该未初始化的指针。因此,它为std::string但不是崩溃int,因为int它是微不足道的,std::string而不是。


这可以通过使用中间变量来解决,这样表达式就不能直接计算为 0:

size_t length = 0;
std::string* p = new std::string[length];
// ...
delete[] p;
于 2012-10-31T13:33:23.927 回答