【发布时间】:2020-01-13 12:00:46
【问题描述】:
给定代码
struct A {};
auto obj = new A;
std::vector<unsigned char> buffer;
buffer.resize(sizeof(obj));
std::memcpy(buffer.data(), &obj, sizeof(obj)); // this copies the pointer, not the object!
// ...
auto ptr = *reinterpret_cast<A**>(buffer.data()); // is this UB?
delete ptr;
在这种情况下,reinterpret_cast 的用法是 UB 吗?我会说是的,因为 memcpy 不会启动实例的生命周期,因此违反了严格的别名规则(这就是为什么 std::bit_cast 已添加到 C++20)。
如果我用另一个memcpy(读取指针)替换演员表,程序是否定义良好?
【问题讨论】:
-
除了语言律师,这完全是错误的。应该是
buffer.data()指向的内容包含指向A的指针,而不是buffer.data()本身是指向A的指针。 -
std::vector分配的内存是否有任何对齐保证? (我认为它的保证是它的分配器保证。) -
我认为它也打破了严格的别名。
-
@anastaciu 在谷歌上的第一击——stats.meta.stackexchange.com/q/5783/3512
-
OK 重新阅读问题后,确实是 UB,因为(1)对齐要求可能被破坏,(2)缓冲区中没有
A*对象。该标准对标准分配器::分配函数进行了说明:“返回:指向大小为n * sizeof(T)的存储数组的初始元素的指针,对于 T 类型的对象适当对齐”。跨度>
标签: c++ language-lawyer