我可以删除[]一个指向已分配数组的指针,但不能删除它的开头吗?

时间:2011-06-21 04:24:34

标签: c++

我特别想知道以下情况(我在一些代码中发现了我必须使用的情况):

SomeClass *ar = new SomeClass[2];
ar++;
delete[] ar;

此代码似乎工作正常 - 即没有崩溃(win32,使用VS2005构建)。

这是“合法的”吗?当然感觉不对。

7 个答案:

答案 0 :(得分:21)

不,未定义将delete的任何地址传递给new。 以下是标准的引用。

§3.7.4.2-3

如果通过抛出异常终止释放函数,则行为未定义。提供给解除分配函数的第一个参数的值可以是空指针值;如果是这样,并且如果解除分配功能是标准库中提供的功能,则该呼叫无效。否则,提供的值 标准库中的运算符delete(void*)应该是先前调用标准库中的运算符new(std::size_t)operator new(std::size_t, const std::nothrow_-t&)返回的值之一,并且值提供给运算符{{1标准库中的标签库应该是前一次调用delete[](void*)或者返回的值之一 标准库中的operator new[](std::size_t)

答案 1 :(得分:20)

不,不合法。您只能deletenew获得的内容,new[]delete[]

完全相同

答案 2 :(得分:7)

不,不是。您必须在从新[]收到的相同地址(或指针)上调用delete []。你可能只是幸运的是它没有崩溃,但它肯定不能恰当地清除内存。

参考文献:

来自http://www.cplusplus.com/doc/tutorial/dynamic/

The value passed as argument to delete must be either a pointer to a memory block
previously allocated with new, or a null pointer (in the case of a null pointer,
delete produces no effect).

来自http://msdn.microsoft.com/en-us/library/h6227113.aspx

Using delete on a pointer to an object not allocated with new gives
unpredictable results. You can, however, use delete on a pointer with the
value 0. This provision means that, when new returns 0 on failure, deleting
the result of a failed new operation is harmless.

答案 3 :(得分:6)

来自标准文档。 5.3.5.2 Delete

  

......在第二个   替换(删除数组),delete的操作数的值应该是由前一个产生的指针值   array new-expression.72)如果不是,则行为未定义。 ....

子注释 72)表明,

  

72)对于非零长度数组,这与指向该new-expression创建的数组的第一个元素的指针相同。零长度数组没有   有第一个元素。

所以是的,它是未定义的。

答案 4 :(得分:1)

该标准规定您只能删除使用new分配的内容,但这并不能解释崩溃原因,或者在这种情况下不会崩溃。

当您删除指针时,您将其放回堆中以便在将来的分配中再次使用。 典型的实现为您提供了一个指针,在您的指针跟踪块中的内存之前使用int(这是典型的malloc实现)。像这样,对于典型的32位系统。

     p-4  size here
p-->     +--------+
         |  your  |
         |  block |

因此,如果你指向块的中间,它将把它之前的字节解释为一个大小,可能带来灾难性的结果。通过您的小代码示例,您可以免于看到崩溃。也许,在那之后你从未尝试过分配。如果你尝试在那之后分配一些东西,它可能会崩溃,因为它会尝试回收你刚刚给回的一些内存。

确切的原因显然取决于实施。这只是为了解释不正确删除可能失败的一种常见方式,而不是针对Visual Studio 2005进行专门验证。

答案 5 :(得分:0)

这是不合法的事实它不会崩溃并不意味着它不会在其他情况下。如果启用验证程序,它肯定会崩溃。无论如何它不会释放你的阵列。这只是CRT / Windows让你的程序在它应该

时不会崩溃

答案 6 :(得分:0)

enter image description here

如果您没有通过它的开头,delete将无法获得额外信息。