UB从免费存储中删除提供存储的char数组时是什么?

问题描述

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:

[expr.delete] 3 在数组删除表达式中,如果要删除的对象的动态类型与静态类型不同,则行为是不确定的。

即使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 (将#修改为@)