Hi,
------------
class A {
public:
~A(){}
void Release(){ delete this; }
};
-----------
A *a = new A();
a->Release(); --> Method I
A a2;
a2.Release(); --> Method II
-----------
a is created in Heap while a2 is in Stack.
When I call "Release()", thus "delete this;" to these two different
kinds of object, what will happen?
If "delete this" just involves calling the destructor, I suppose they
are equivalent.
Any suggestions? Thanks.
tom
|
|
0
|
|
|
|
Reply
|
freshthomas (139)
|
10/15/2010 4:22:48 AM |
|
On Oct 15, 9:22=A0am, thomas <freshtho...@gmail.com> wrote:
> Hi,
>
> ------------
> class A {
> public:
> =A0 =A0 =A0 ~A(){}
> =A0 =A0 =A0 =A0void Release(){ delete this; }};
>
> -----------
> A *a =3D new A();
> a->Release(); =A0 =A0 =A0 --> =A0 =A0Method I
> A a2;
> a2.Release(); =A0 =A0 =A0--> =A0 =A0Method II
> -----------
>
> a is created in Heap while a2 is in Stack.
> When I call "Release()", thus "delete this;" to these two different
> kinds of object, what will happen?
> If "delete this" just involves calling the destructor, I suppose they
> are equivalent.
> Any suggestions? Thanks.
>
> tom
Calling delete on an object for which memory has not been allocated
explicitly using *new* invokes Undefined Behaviour.
Undefined Behaviour means *anything* can happen. Don't write such code.
|
|
0
|
|
|
|
Reply
|
prasoonsaurav.nit
|
10/15/2010 4:58:06 AM
|
|
On Oct 15, 9:22=A0am, thomas <freshtho...@gmail.com> wrote:
> Hi,
>
> ------------
> class A {
> public:
> =A0 =A0 =A0 ~A(){}
> =A0 =A0 =A0 =A0void Release(){ delete this; }};
>
> -----------
> A *a =3D new A();
> a->Release(); =A0 =A0 =A0 --> =A0 =A0Method I
> A a2;
> a2.Release(); =A0 =A0 =A0--> =A0 =A0Method II
> -----------
>
> a is created in Heap while a2 is in Stack.
> When I call "Release()", thus "delete this;" to these two different
> kinds of object, what will happen?
> If "delete this" just involves calling the destructor, I suppose they
> are equivalent.
> Any suggestions? Thanks.
>
> tom
Calling delete on something,memory for which, has not been allocated
explicitly using *new* invokes Undefined Behaviour.
Undefined Behaviour means *anything* can happen. Don't write such
code.
|
|
0
|
|
|
|
Reply
|
prasoonsaurav.nit
|
10/15/2010 5:00:33 AM
|
|
On Oct 15, 6:22=A0am, thomas <freshtho...@gmail.com> wrote:
> Hi,
>
> ------------
> class A {
> public:
> =A0 =A0 =A0 ~A(){}
> =A0 =A0 =A0 =A0void Release(){ delete this; }};
>
> -----------
> A *a =3D new A();
> a->Release(); =A0 =A0 =A0 --> =A0 =A0Method I
> A a2;
> a2.Release(); =A0 =A0 =A0--> =A0 =A0Method II
> -----------
>
> a is created in Heap while a2 is in Stack.
> When I call "Release()", thus "delete this;" to these two different
> kinds of object, what will happen?
> If "delete this" just involves calling the destructor, I suppose they
> are equivalent.
> Any suggestions? Thanks.
>
> tom
Hi,
Make sure you read this FAQ:
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.15
You cannot call delete for objects allocated on the stack (amongst
others - see FAQ). This means that you have to make sure your
objects are heap allocated. You could do this by making the
constructor private and having a static function that returns
a heap instance.
class A
{
public:
void Release(){ delete this; }
static std::auto_ptr<A> makeA()
{
return std::auto_ptr<A>( new A );
}
private:
A(){ }
};
I just use an auto pointer here because it makes
it clear that the caller takes ownership of the
pointer (assuming he calls the function that eventually
performs deallocation.
Kind regards,
Werner
|
|
0
|
|
|
|
Reply
|
werasm (308)
|
10/15/2010 5:36:35 AM
|
|
On Oct 15, 6:22=A0am, thomas <freshtho...@gmail.com> wrote:
> Hi,
>
> ------------
> class A {
> public:
> =A0 =A0 =A0 ~A(){}
> =A0 =A0 =A0 =A0void Release(){ delete this; }};
>
> -----------
> A *a =3D new A();
> a->Release(); =A0 =A0 =A0 --> =A0 =A0Method I
> A a2;
> a2.Release(); =A0 =A0 =A0--> =A0 =A0Method II
> -----------
>
> a is created in Heap while a2 is in Stack.
> When I call "Release()", thus "delete this;" to these two different
> kinds of object, what will happen?
> If "delete this" just involves calling the destructor, I suppose they
> are equivalent.
Not at all. operator delete invokes the destrucctor and then frees
allocated memory. Just like operator new allocates memory, then calls
the constructor. That's a rather fundamental aspect of what they do.
> Any suggestions? Thanks.
Others already explained.
I'll add this: "delete this" is in general a bloody stupid idea with
rare situations where it's expedient. Your snippet is just a massive
bug.
C++ language, however, does allow you to design a type so that clients
have to use it on the heap, and that you have to call e.g. a Release
function (name is incidental). E.g.
class heap_only_please
{ // intentionally private:
heap_only_please() {...}
heap_only_please(const heap_only_please& ) {...};
~heap_only_please() {...}
heap_only_please(params) {...}
public:
static heap_only_please* create(params)
{
return new heap_only_please(params);
}
void Release() { delete this; }
// Want refcounting? Put it in Release! ;-)
};
Goran.
|
|
0
|
|
|
|
Reply
|
goran.pusic (299)
|
10/15/2010 8:49:43 AM
|
|
|
4 Replies
118 Views
(page loaded in 0.603 seconds)
|