将运算符 new[] 和放置 new 与普通 delete[] 混合

Mixing operator new[] and placement new with ordinary delete[](将运算符 new[] 和放置 new 与普通 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[] 混合

基础教程推荐