在p = new string [0]和p = new int [0]之后,为什么删除[] p时字符串版本会崩溃?

时间:2012-10-31 13:17:12

标签: c++ pointers new-operator delete-operator

我有两段关于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++而没有任何参数来编译它。

如果是编译器错误,它们是否会根据标准崩溃?

1 个答案:

答案 0 :(得分:13)

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

  

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

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


只有当要构造的类型具有任何非平凡的构造函数时,才会存在消除 - new[]错误。并且segfault发生类型具有析构函数,因为delete[]将需要取消引用该未初始化的指针。因此,std::stringint崩溃,因为int是微不足道的,而std::string则不是。{/ p>


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

size_t length = 0;
std::string* p = new std::string[length];
// ...
delete[] p;