通过访问对象reinterpret_cast
ed 指针和相关的 UB 已经在这里进行了广泛的讨论。阅读问题和答案后,我仍然不确定是否正确使用 POD 类型的未初始化内存。
假设我想“模仿”
struct { double d; int i; };
通过手动为数据成员分配内存并假设(为了简单起见)之前不需要填充i
.
现在,我这样做:
// (V1)
auto buff = reinterpret_cast<char*>(std::malloc(sizeof(double) + sizeof(int)));
auto d_ptr = reinterpret_cast<double*>(buff);
auto i_ptr = reinterpret_cast<int*>(buff + sizeof(double));
*d_ptr = 20.19;
*i_ptr = 2019;
第一个问题:这个代码有效吗?
我可以使用放置new
:
// (V2)
auto buff = reinterpret_cast<char*>(std::malloc(sizeof(double) + sizeof(int)));
auto d_ptr = new(buff) double;
auto i_ptr = new(buff + sizeof(double)) int;
*d_ptr = 20.19;
*i_ptr = 2019;
我一定要吗?放置new
这里似乎是多余的,因为 POD 类型的默认初始化是无操作(空初始化),并且[基本生活] reads:
类型对象的生命周期T
开始于:
(1.1) 按类型正确对齐和大小存储T
得到,
(1.2) 如果对象具有非空初始化,则其初始化完成,...
这是不是说寿命*d_ptr
and *i_ptr
一旦我为它们分配了内存,对象就开始了?
第二个问题:我可以使用 typedouble*
(或一些T*
) for buff
, i.e.
// (V3)
auto buff = reinterpret_cast<double*>(std::malloc(sizeof(double) + sizeof(int)));
auto d_ptr = reinterpret_cast<double*>(buff);
auto i_ptr = reinterpret_cast<int*>(buff + 1);
*d_ptr = 20.19;
*i_ptr = 2019;
or
// (V4)
auto buff = reinterpret_cast<double*>(std::malloc(sizeof(double) + sizeof(int)));
auto d_ptr = new(buff) double;
auto i_ptr = new(buff + 1) int;
*d_ptr = 20.19;
*i_ptr = 2019;
?