3

在我对幸福的无尽追求中,我遇到了这样的事情

auto temp = new int;
delete[0] temp;

在我看来,我就像...... “这不可能!” 所以我启动了最特别和最叛逆的雪花编译器来测试它,你瞧,它编译并运行没有任何问题!

然后我在 GCC (4.8.1) 中尝试了它并拒绝它并出现此错误

错误:数字常量前应为“]”

那请问各位同志,哪一个是对的?(当然不是 MSVC(11) ?!)如果你能引用标准,那就太好了。

4

4 回答 4

12

回到 C++ 的黎明,当你删除一个数组时,你需要指定你分配的数组的大小:

int * x = new int[10];
// ...
delete [10] x;

这导致了很多问题,所以这个要求很早就被取消了。在编写第一个 C++ 标准时,正式不再允许这种语法。

尽管如此,为了与使用它的旧代码兼容,许多编译器仍然接受这种语法。对于 MS VC++,这是默认接受的,但如果您要求符合标准 (-Za),您将收到如下错误:

error C2203: delete operator cannot specify bounds for an array

除了强制性的:无论如何,您都不应该使用它new来分配数组。使用std::vector.

于 2013-09-20T07:38:03.693 回答
5

delete[0]根据当前标准是非法语法..

另外,当你用 分配一个对象时new,你应该用和delete释放它。它们不应该是可互换的。new []delete []

C++11 §5.3.5 删除

delete-expression 运算符破坏由 new-expression 创建的最派生对象 (1.8) 或数组。

删除表达式:

::opt delete cast-expression

::opt delete [ ] cast-expression

第一种选择用于非数组对象,第二种选择用于数组。操作数应具有指针类型,或具有单个转换函数(12.3.2)到指针类型的类类型。结果有类型void

于 2013-09-20T07:37:33.333 回答
3

该标准知道两种不同类型的存储释放,单对象形式的存储释放,18.6.1.1/10-19,即

void operator delete(void * ptr) noexcept;
void operator delete(void * ptr, std::nothrow_t const &) noexcept;

和数组形式的存储释放,18.6.1.2/9-17,即

void operator delete[](void * ptr) noexcept;
void operator delete[](void * ptr, std::nothrow_t const &) noexcept;

但是,从历史上看(标准前)有一个delete[N]释放器,它要求您释放与为数组分配的一样多的空间。我怀疑这就是您的编译器正在解释的内容。

于 2013-09-20T07:39:56.203 回答
0

它运行没有问题,因为你很幸运。通常用 new 分配和用 delete[] 删除是未定义的行为,“运行没有任何问题”属于 UB 允许的行为集。像这样的代码有时在测试中运行良好,但在最意想不到的时刻中断,例如为您最重要的客户提供现场演示。

于 2013-09-20T07:56:04.413 回答