Given the code
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;
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).
And if I replace the cast with another memcpy
(to read the pointer) would the program be well defined?
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;
would be fine.
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…
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With