delete []提供了一个修改过的new-ed指针。未定义的行为?

时间:2009-04-25 07:50:58

标签: c++ memory-management new-operator standards-compliance

在对等代码审核会话期间,我看到了以下代码:

char *s = new char[3];
*s++ = 'a';
*s++ = 'b';
*s++='\0';
delete []s; // this may or may not crash on some or any day !!

首先,我知道在标准C ++中,指向一个过去的数组大小是O.K.虽然访问它会导致未定义的行为。所以我相信最后一行*s++='\0'没问题。但是如果我没记错的话,C ++标准要求delete应该提供new返回的相同指针。

我相信这意味着返回的指针不得被篡改。我想这是因为new可能会在delete可能使用的返回地址之前保留一些内务信息。移动new'd指针可能会使其无法访问。

是未定义的行为还是实现定义或未指定? 有谁能确认一下吗?最好通过指向C ++标准中的正确位置。

在C ++标准草案(Draft_SC22-N-4411.pdf)的免费草案版本中,详情见5.3.5节。我是从Bjarne的主页上得到的。

3 个答案:

答案 0 :(得分:17)

从C ++标准,第5.3.5 / 2节:

  

delete的操作数的值应为指针值   这是由前一个数组产生的   新的表达。如果没有,行为   未定义

答案 1 :(得分:4)

是的,你必须删除[]你给新的原始指针;在这种情况下,这将是指向数组头部的指针,而不是尾部。这里的代码是删除一些其他未指定的随机对象。

答案 2 :(得分:3)

是的,回想一下这是如何实现的:new真的调用malloc,它返回一个指向(void*)(&(((int*)p)[1]))的指针,其中p是分配的内存的实际开始,第一个int是实际的大小记忆我们回来了。

我们返回的指针是在分配的实际内存中进一步的sizeof(int)(或任何对齐需要)。我们将物体放在那里,使实际尺寸不受干扰。

然后当该指针传递给delete时,将其传递给free,free会在传递指针之前查找一个int ,以查找正在返回的大小。

传回我们得到的东西之外的其他东西意味着自由认为任意数量的实际内存被传回,并且它会相应搞砸自由列表。

同样,这是经常实现的方式,而不是如何实现new,delete,malloc或free。