问题描述
cppreference page的早期版本提供了以下使用placement-new的示例:
char* ptr = new char[sizeof(T)]; // allocate memory
T* tptr = new(ptr) T; // construct in allocated storage ("place")
tptr->~T(); // destruct
delete[] ptr; // deallocate memory
受this comment on an older SO thread的启发,我得出的结论是这可能是UB。但是,在该cppreference文章的讨论页面上,对于这种情况是否确实存在进行了少量讨论。
评论基于此标准摘录,可能表明它可能是UB:
即使T的生命周期结束了,这也适用吗? 编辑:正如Language Lawyer在评论中所指出的:ptr的动态类型保持不变,因此这并不适用。
[basic.life]另一方面说:(我加粗的部分)
[...]在对象的生存期结束之后并且在重新使用或释放该对象所占用的存储之前,可以使用任何表示该对象将位于或位于的存储位置的地址的指针。但仅限于有限的方式。 [...]这样的指针引用已分配的存储空间([basic.stc.dynamic.allocation]),并且使用该指针时就像该指针的类型为void *是明确定义的。 (请注意:[exp.delete]注意“无法使用类型为void *的指针删除对象”) 允许通过此类指针进行间接访问,但是生成的左值只能以有限的方式使用,如下所述。 该程序具有以下不确定行为::
-该对象将是或曾经是具有非平凡析构函数的类类型,并且该指针用作delete-expression的操作数,
...
由于char []不是具有非平凡析构函数的类类型,因此这不适用于该段的显式未定义行为的列表中的其他元素。但是,这是否暗示 定义明确?那个具体的要点似乎表明,可能是析构函数不匹配会带来问题,这在这里不适用。
此外,其措辞是“在对象所占用的存储被重用之前”,但是从技术上讲,它已经被重用了,只是被重用它的对象不再存在了。在此处可能只允许使用指向该存储中寿命最近的对象的指针。
结论:在为已销毁的另一个对象提供存储后,UB是否要删除动态分配的char数组?如果是,那么是否有合法的方法可以完全取消分配它,还是应该将其完全替换为显式的运算符new / operator delete组合,例如标准分配器的工作方式?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)