delete[] 提供了一个修改后的新指针。 未定义的行为?

发布于 2024-07-18 09:58:41 字数 657 浏览 11 评论 0原文

我在同行代码评审会议期间看到了如下代码:

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++ 中,指向数组大小的前一位是可以的,尽管访问它会导致未定义的行为。 所以我相信最后一行 *s++='\0' 没问题。 但如果我没记错的话,C++ 标准要求为 delete 提供与 new 返回的指针相同的指针。

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

它是未定义的行为还是实现定义的或未指定的? 有人可以证实这一点吗? 最好通过指向 C++ 标准中的正确位置。

在免费提供的 C++ 标准草案 (Draft_SC22-N-4411.pdf) 草案版本中,第 5.3.5 节提供了详细信息。 我从 Bjarne 的主页上得到的。

I saw some code as below during a peer-code-review session:

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

Firstly, I know that in Standard C++, pointing to one-past the array-size is O.K. though accessing it results in undefined behaviour. So I believe the last line *s++='\0' is fine. But if I recall correctly, the C++ standard mandates that delete should be supplied the same pointer that new returned.

This I believe means that the returned pointer must not be tampered-with. I guess it is because new might keep some housekeeping info before the returned address that delete might use. Moving the new'd pointer might make this inaccessible.

Is it undefined behaviour or implementation-defined or unspecified?
Can anyone confirm this please? Preferably by pointing to the correct place in the C++ Standard.

In the freely available draft version of the draft C++ Standard (Draft_SC22-N-4411.pdf) has the details in section 5.3.5. I got it from Bjarne's homepage.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薄凉少年不暖心 2024-07-25 09:58:41

来自 C++ 标准,第 5.3.5/2 节:

delete操作数的值为指针值
这是由先前的数组产生的
新表达。 如果不是,则行为
未定义

From the C++ Standard, section 5.3.5/2:

the value of the operand of delete shall be the pointer value
which resulted from a previous array
new-expression. If not, the behaviour
is undefined

め七分饶幸 2024-07-25 09:58:41

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

Yes, you must delete[] the original pointer you were given by new; in this case, that would be a pointer to the head of the array, rather than the tail. The code here is deleting some other unspecified random object.

我们只是彼此的过ke 2024-07-25 09:58:41

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

我们返回的指针是实际分配的内存中的一个 sizeof(int) (或任何对齐要求)。 我们将物体放在那里,保持实际尺寸不变。

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

传回我们所得到的以外的东西将意味着 free 认为正在传回任意数量的实际内存,并且它会相应地搞乱空闲列表。

同样,这就是它通常的实现方式,而不是 new、delete、malloc 或 free 需要如何实现。

Yeah, recall how this is often implemented: new really calls malloc, which gives back a pointer to (void*)(&(((int*)p)[1])), where p is the actual start of the memory allocated, and the first int is the size of the actual memory we got back.

The pointer we get back is one sizeof(int) (or whatever alignment requires) further along in the actual memory allocated. We lay down our object there, leaving the actual size undisturbed.

Then when that pointer passed to delete, which passes it to free, free looks one int before the passed pointer, to find the size that's being given back.

Passing back something other than what we got is going to mean that free thinks an arbitrary amount of actual memory is being passed back, and it'll screw up the free list accordingly.

Again, this is how it's often implemented, not how new, delete, malloc, or free are required to be implemented.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文