|
Boost : |
From: Bo Persson (bop2_at_[hidden])
Date: 2003-10-11 05:41:09
"E. Gladyshev" <egladysh_at_[hidden]> skrev i meddelandet
news:20031011082922.79668.qmail_at_web40808.mail.yahoo.com...
>
> I know you all are sick and tired of it, but I am not.
> Please help me to understand it.
> I posted the same question to the c++ news group.
>
>
> struct my_type
> {
> f() {}
> };
>
> /*
> 5.3.4/8 (C++ Standard)
> [...]
> [Note: since allocation functions are assumed to return pointers
to
> storage that is appropriately aligned for objects of any type,
this
> constraint on array allocation overhead permits the common
idiom of
> allocating character arrays into which objects of other types
will
> later be placed. ]
> */
>
> char buf[sizeof(my_type)]; //5.3.4/8 -> can safely allocate my_type
in buf
>
> my_type* p1 = new( buf ) my_type;
>
> /*
> according to 5.3.4/9
> "The address of the created object will not necessarily be the
same as
> that
> of the block of storage if the object is an array."
>
> We are not allocating an array, so p1 == buf !!!
> */
>
> p1->f(); //ok
>
>
> /*
> 3.8/4
> "A program may end the lifetime of any object by reusing the storage
> which the object occupies"
> */
> my_type* p2 = new( buf ) my_type; //reusing *p1 storage
>
> //NOTE: according to 5.3.4/9, p2 == buf !!!
>
> p2->f(); //ok
> p1->f(); //undefined (according to 3.8/4) -- lifetime of *p1 is
ended
>
> At this point,
> 'p2' is equal to 'p1' and they pointing to the same data type,
> p1->f() is undefined, so that p2->f() is undefined.
>
> So, p2 = new(buf) my_type; returned a pointer
> to an object of 'my_type' type with an undefined
> behavior.
>
> I must be doing something stupid. What?
You are making it all too difficult for you! :-)
p1 is invalid, because the object it pointed to is gone. That's all.
p2 is valid because it points to another object. That this object
reuses the same space has no importance.
Consider a few other examples:
int* p1a = new int(42);
int* p1b = p1a;
Now p1a and p1b both points to the same object, and both are valid.
delete p1b;
Now none of them are valid!
int* p1 = new int(12);
delete p1;
int* p2 = new int;
On some systems p2 will now point at the same space that p1 formerly
used. But p1 is invalid and p2 is valid. This is about what you did,
even though you did in the most difficult way.
Bo Persson
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk