c++ - Overwriting an object with an object of same type -
is following defined?
#include <iostream> #include <string.h> using namespace std; struct const { const int i; const (int i) : i(i) {} int get0() { return 0; } // best accessor ever! }; int main() { const *q,*p = new const(1); new (p) const(2); memcpy (&q, &p, sizeof p); cout << q->i; return 0; } note after construction of second const, p doesn't semantically (intentionally?) points new object, , first gone, usable "as void*". second object constructed @ exact same address, bit pattern of p represents address of new object.
comment
new (p) const(2) erase old object stored @ p, pointer not valid anymore, except pointer storage (void*).
i want recover value of p const*.
comment 2
after either p->~const() or memset (p, 0, sizeof *p) clear p not point valid object, p can used pointer storage (void* or char*), example reconstruct object. @ point p->get0() not allowed.
here demolition of old object done constructor of new one, don't think makes difference.
my intuition that: in case, old object gone, , p points old object, not new one.
i looking confirmation or refutation based on standard.
see also
i have asked same question pointers, in c , c++ :
- dereferencing out of bound pointer contains address of object (array of array)
- is memcpy of pointer same assignment?
- are pointer variables integers operators or "mystical"?
please read these discussions before answering "this ridiculous".
(making community-wiki incorporating dyp's comment re 3.8/7 significant; while earlier analysis correct have said same things code broken, having overlooked 3.8/7 myself)
const *q,*p = new const(1); new (p) const(2); the new(p) const(2); line overwrites object had been constructed const(1).
memcpy (&q, &p, sizeof p); this equivalent q = p;.
cout << q->i; this accesses q->i member, 2.
the noteworthy things are:
std::memcpyugly way assignpq... legal though under 3.9/3:
for trivially copyable type
t, if 2 pointerstpoint distincttobjectsobj1,obj2, neitherobj1norobj2base-class subobject, if underlying bytes (1.7) makingobj1copiedobj2,obj2shall subsequently hold same valueobj1. [ example:
t* t1p; t* t2p; // provided t2p points initialized object ... std::memcpy(t1p, t2p, sizeof(t)); // @ point, every subobject of trivially copyable type in *t1p contains // same value corresponding subobject in *t2p the overwriting of old
const(1)objectconst(2)allowed long program doesn't depend on side effects of former's destructor, doesn't.(as dyp noted in comments below) ongoing access
const(2)object usingpillegal under 3.8/7's third point:
pointer pointed original object [...] can used manipulate new object, if...
- the type of original object not
const-qualified, and, if class type, not contain non-static data member typeconst-qualified or reference type ...
- using
q- ratherp- accessipresumably necessary avoid compiler optimisations based on presumed knowledge ofi.
as commentary:
note after construction of second
const,pdoesn't semantically (intentionally?) points new object, , first gone, usable "asvoid*".
given placement-new object @ address contained in p, p point newly created object, , intentionally, can't used manipulate object under 3.8/7 above.
given seem have notion of "semantically pointing" that's not defined in c++ truth of part of statement's in own mind.
'after construction of second const, p...is usable "as void*' makes no sense... it's not more usable beforehand.
but second object constructed @ exact same address, bit pattern of
prepresents address of new object.
of course, comments show think "bit pattern" somehow distinct value of pointer applies assignment =, not true.
new (p) const(2)erase old object stored @p, pointer not valid anymore, except pointer storage (void*).
"erase" strange term it... overwrites more meaningful. dyp noted , explained above, 3.8/7 says shouldn't "manipulate" object p points after placement new, value , type of pointer unaffected placmeent new. can call f(void*) pointer type, placement-new doesn't need know or care type of p expression.
after either
p->~const()ormemset (p, 0, sizeof *p)clearpnot point valid object,pcan used pointer storage (void*orchar*), example reconstruct object. @ pointp->get0()not allowed.
most of that's true, if "p can used" mean value of p @ time rather pointer (which can of course assigned to). , you're trying little clever void* / char* thing - p remains const*, if it's used placement new doesn't care pointee type.
"i want recover value of
pconst*."
the value of p not changed after first initialised. placement-new uses value - not modify it. there's nothing recover nothing lost. said, dyp's highlighted need not use p manipulate object, while value wasn't lost it's not directly usable wanted either.
Comments
Post a Comment