是否在memcpy缓冲区UB上使用了reinterpret_cast? [英] Is the usage of reinterpret_cast on a memcpy buffer UB?

查看:57
本文介绍了是否在memcpy缓冲区UB上使用了reinterpret_cast?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出代码

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;

在这种情况下UB是 reinterpret_cast 的用法吗?我会说是的,因为 memcpy 不会启动实例的生存期,因此违反了严格的别名规则(这就是为什么 std :: bit_cast 已添加到C ++20).

is the usage of reinterpret_cast in this case UB? I would say yes, because memcpy doesn't start the lifetime of an instance hence violating the strict aliasing rule (which is why std::bit_cast has been added to C++20).

如果我用另一个 memcpy 替换演员表(以读取指针),程序会被很好地定义吗?

And if I replace the cast with another memcpy (to read the pointer) would the program be well defined?

推荐答案

是的,此代码具有未定义的行为.在 buffer.data()所指向的位置没有类型为 A * 的对象.您要做的就是将此类指针的对象表示形式复制到向量basic.types]/4 .由于指针很容易复制,因此 [basic.types]/9 ,如果您将这些字节复制回 A * 类型的实际对象,然后 delete 的值,则定义明确的

Yes, this code has undefined behavior. There is no object of type A* at the location pointed to by buffer.data(). All you did was copy the object representation of such a pointer into your vector [basic.types]/4. Since pointers are trivially copyable [basic.types]/9, if you were to copy back these bytes into an actual object of type A* and then delete the value of that, that would be well-defined [basic.types]/3. So this

A* ptr;
std::memcpy(&ptr, buffer.data(), sizeof(ptr));
delete ptr;

会没事的.

请注意,不是强制转换本身在原始示例中调用了未定义的行为,而是您随后尝试读取类型为 A * 的对象的值,该对象在通过指针获取指针时不存在演员表指针指向的所有内容都是一个 unsigned char 类型的对象序列. A * 类型不是您可以用来访问 unsigned char 类型的对象的存储值的类型

Note that it is not the cast itself that invokes undefined behavior in your original example but your subsequent attempt to read the value of an object of type A* which does not exist where the pointer obtained via the cast points. All there exists where the pointer points is a sequence of objects of type unsigned char. The type A* is not a type that you may use to access the stored value of an object of type unsigned char [basic.lval]/8…

这篇关于是否在memcpy缓冲区UB上使用了reinterpret_cast?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆