delete this

Started by
21 comments, last by Qw3r7yU10p! 19 years, 7 months ago
Basically I am allocating memory as follows:

Object *objs;
objs = new Object[someint];
Now I need to release the memory within the class itself like:

class Object
{
...
void Something()
{
if(whatever)
{
delete this;
}
}
};
If I call delete this within all the dynamically allocated objects will all the memory be perfectly freed again? Also is this bad practice, or even not possible? -CProgrammer
Advertisement
It is perfectly fine to delete this as long as you aren't using the object after the delete in your function (or anytime after the function exits). This is actually pretty common when working with objects across DLLs, often times coupled with reference counting. Calling delete on an object not allocated in the same executable is not legal, so you make a virtual function that does the deleting when you call it (that way the object is always deallocated from a function in their own executable). One place you will see this a lot that I'm sure you've worked with is COM interfaces. An extremely common way of implementing Release for a COM interface is to delete this when the interface reference count reaches 0 (so the odds are that all of your directx interfaces have a delete this line in their release functions).

Edit: After rereading I noticed you are attempting to delete elements of a dynamically allocated array individually. Don't do that! Only call delete this if the object itself was dynamically allocated with new.

[Edited by - Polymorphic OOP on September 18, 2004 10:12:00 PM]
Yeah I looked at some COM code and your right. Thanks for the info.
-CProgrammer
It is TOTALLY OK, and TOTALLY NORMAL ... but remember, don't ever delete this in any function, in any way, that the client wouldn't be expecting the object to be deleted ... cause the client has no way to check if a pointer is valid or not ...

if a client does this:

YourClass x = new YourClass();
...
x->DoStuff();

// the client must KNNOW, 100% if the x obect has been deleted ...

because first of all, if the client then does

x->DoOtherStuff();

on a deleted object, program should now crash with a seg fault.

second, if client does:

delete x;

on an already deleted object, program should crash also ...

so it is FINE for something like:

x->Release();

to delete this IF the ref count is 0, cause the rules of using the x object are such that NO CLIENT SHOULD be manually deleting x, and also no client should be doing anything to x whatsoever after the Release call ...

so basically - delete this; is only viable inside of functions who's job is to manage the life of the object ...
Quote:Original post by CProgrammer
If I call delete this within all the dynamically allocated objects will all the memory be perfectly freed again?

Yes, it really makes no diference, for instance, the following produce the same result:
// example 1MyObject *array = MyObject[1024];delete [] array;// example 2MyObject *array = MyObject[1024];for (unsigned int i = 0; i < 1024; i++)delete array + i;

And yes, I know c++ purists will complain about that pointer addition, having been recently flamed on the point, but really, is delete &array any better?<br><br>[edit] At first glance, i thought this topic's title was a request for a moderator to remove the topic ;)[/edit]<br>SwiftCoder

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Quote:Original post by swiftcoder
Quote:Original post by CProgrammer
If I call delete this within all the dynamically allocated objects will all the memory be perfectly freed again?

Yes, it really makes no diference, for instance, the following produce the same result:
*** Source Snippet Removed ***
And yes, I know c++ purists will complain about that pointer addition, having been recently flamed on the point, but really, is delete &array any better?<!–QUOTE–></td></tr></table></BLOCKQUOTE><!–/QUOTE–><!–ENDQUOTE–><br><br>Nonono!!! Don't EVER do that. Those two examples do NOT do the same thing. In fact, example two is not legal! You can never call delete &#111;n the individual elements of a dynamically allocated array and think that it will deallocate the elements individually. You will get undefined results (which will often cause a program crash, or worse, your program won't crash but it will be in an undeterminable state). The &#79;NLY valid way to deallocate a dynamically allocated array in C++ is to call delete [] &#111;n the pointer to the first element of the array.
CProgrammer, the answer to your question is no. You must delete an allocation the same way you new it. swiftcoder is wrong. His example does not work. If you allocate an array like this:
    Object *objs = new Object[someint]; 
You must delete it like this:
    delete [] objs; 
You cannot do this:
    for ( int i = 0; i < someint; i++ )    {        delete &objs;    }or    for ( int i = 0; i < someint; i++ )    {        objs.FunctionThatContainsDeleteThis();    } 
If you want to delete indvidual objects in an array, you need an array of pointers like this:
    Object * apObjs[ someint ];    for ( int i = 0; i < someint; i++ )    {        apObjs = new Object;    } 
Then you can/must delete the objects like this:
    for ( int i = 0; i < someint; i++ )    {        delete apObjs;    }or    for ( int i = 0; i < someint; i++ )    {        apObjs->FunctionThatContainsDeleteThis();    } 


Other than that, delete this is a bad idea if you can't guarantee that the object was allocated with new, and not new[] or on the stack or as a member variable.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Sorry, my bad, i was thinking of Objective-C :(

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Well thanks for clearing that up guys. I'll just make sure its allocated with 'new' then.

-CProgrammer
Actually im using 'delete this' for instances of objects.

Basically an instance is pushed into a quadtree. If the object is to be deleted the quadtree calls a member function including 'delete this'.
By the way does a call to the constructor as
Add(CInstance(...));
count as a 'new' call. Id think so just making sure.

-CProgrammer

This topic is closed to new replies.

Advertisement