提问人:JMC 提问时间:9/1/2023 更新时间:9/1/2023 访问量:106
C++ 更改不允许使用动态分配的数组作为存储提供程序?
C++23 changes disallow using dynamically allocated array as storage provider?
问:
这是使用动态无符号 char 数组作为 T 型的“存储”的基本示例。
unsigned char* storage = new unsigned char[sizeof(T)];
T* foo = new(storage) T; // line 2
// use *foo somehow
foo->~T(); //destroy our foo
delete[] storage; // Undefined as of C++23? How else to do it?
在第 2 行之后,数组本身仍然处于活动状态,因为它为嵌套在数组中的 T 提供存储,但数组元素现在应该超出生存期,因为它们的存储已被 T 重用,并且 T 不嵌套在它们中,只嵌套在数组本身中。
但是,在使用完这个数组后,我们如何使用指针删除它,它是指向生命周期外第一个元素的指针?foo
直到(排除)C++23 [basic.life]/6 建议允许或至少不禁止在表达式中使用此指针:delete
如果出现以下情况,程序具有未定义的行为: (6.1) 对象将属于或曾经是具有非平凡析构函数的类类型,并且指针用作删除表达式的操作数,
这不适用于 IT'S NOT A CLASS TYPE。但是,从 C++23 开始,这句话改为unsigned char
如果出现以下情况,程序具有未定义的行为:(6.1) 指针用作删除表达式的操作数,
现在包括 .unsigned char
这是否意味着不再可能以这种方式使用 char-array 作为存储?
到目前为止,我对该标准的研究给了我 3 种可能的质疑:
它可能与现在被定义为无符号字符数组的“对象表示”有关,这意味着指针现在可能指向一个新的无符号字符,这是“对象表示”的一部分,因此仍然有效,或者
整个 basic.life/6 paragrah 不应该在这里适用,因为它说:
在对象占用的存储被重用之前
这已经发生了,尽管这种重用也再次通过调用 或~T()
- 考虑到 -expression 无论如何都不允许我们指定所需的对齐方式,这甚至有可能从未适用于使用 -expression 创建的数组吗?
new
new
以下哪一项(如果有的话)可能是正确的?
答: 暂无答案
评论
delete[] storage;
new (storage) unsigned char[original_size];
delete[] storage;
p->~T()
unsigned char[]
unsigned char[]
delete[]
unsigned char[]
delete[] storage