Mixing operator new[] and placement new with ordinary delete[](将运算符 new[] 和放置 new 与普通 delete[] 混合)
问题描述
出于好奇,以下是否合法?
Just out of curiosity, is the following legal?
X* p = static_cast<X*>(operator new[](3 * sizeof(X)));
new(p + 0) X();
new(p + 1) X();
new(p + 2) X();
delete[] p; // Am I allowed to use delete[] here? Or is it undefined behavior?
同样:
X* q = new X[3]();
(q + 2)->~X();
(q + 1)->~X();
(q + 0)->~X();
operator delete[](q);
推荐答案
我很确定两个都给 UB.
I'm pretty sure both give UB.
§5.3.4/12 说新表达式的数组形式可能会给分配的内存量增加一些任意数量的开销.数组 delete 可以/可以使用它期望在那里的额外内存做一些事情,但不是因为你没有分配它期望的额外空间.至少它通常会至少补偿它预期分配的额外内存量,以返回它认为从 operator new
返回的地址——但因为你还没有分配了额外的内存或应用了偏移量,当它这样做时,它将传递一个指向 operator delete[]
的指针,该指针不是从 operator new[]
返回的,导致UB(事实上,即使尝试在返回地址的开头之前形成地址在技术上也是 UB).
§5.3.4/12 says the array form of a new expression may add some arbitrary amount of overhead to the amount of memory allocated. The array delete can/could then do something with the extra memory it expects to be there, but isn't since you didn't allocate the extra space it expects. At the very least it's normally going to at least compensate for the amount of extra memory it expected to be allocated to get back to the address it believes was returned from operator new
-- but since you haven't allocated extra memory or applied an offset, when it does to it'll pass a pointer to operator delete[]
that wasn't returned from operator new[]
, leading to UB (and, in fact, even attempting to form the address before the beginning of the returned address is technically UB).
同一部分说,如果它分配额外的内存,它必须将返回的指针偏移该开销的量.当/如果您使用从新表达式返回的指针调用 operator delete[]
而不补偿偏移量,则您正在使用指针调用 operator delete[]
这与返回的 operator new[]
不同,再次给 UB.
The same section says that if it allocates extra memory, it has to offset the returned pointer by the amount of that overhead. When/if you call operator delete[]
with the pointer that was returned from the new expression without compensating for the offset, you're calling operator delete[]
with a pointer that's different from the one operator new[]
returned, giving UB again.
§5.3.4/12 是非规范性注释,但我在规范性文本中没有看到任何与之相矛盾的内容.
§5.3.4/12 is a non-normative note, but I don't see anything in the normative text to contradict it.
这篇关于将运算符 new[] 和放置 new 与普通 delete[] 混合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:将运算符 new[] 和放置 new 与普通 delete[] 混合
基础教程推荐
- Windows Media Foundation 录制音频 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01