Is it safe to `delete this`? [duplicate] - c++

This question already has answers here:
Is "delete this" allowed in C++?
(10 answers)
Closed 5 years ago.
In my initial basic tests it is perfectly safe to do so. However, it has struck me that attempting to manipulate this later in a function that deletes this could be a runtime error. Is this true, and is it normally safe to delete this? or are there only certain cases wherein it is safe?

delete this is legal and does what you would expect: it calls your class's destructor and free the underlying memory. After delete this returns, your this pointer value does not change, so it is now a dangling pointer that should not be dereferenced. That includes implicit dereferencing using the class's member variables.
It is usually found in reference-counted classes that, when the ref-count is decremented to 0, the DecrementRefCount()/Release()/whatever member function calls delete this.
delete this is typically considered very bad form for many reasons. It is easy to accidentally access member variables after delete this. Caller code might not realize your object has self-destructed.
Also, delete this is a "code smell" that your code might not have a symmetric strategy for object ownership (who allocates and who deletes). An object could not have allocated itself with new, so calling delete this means that class A is allocating an object, but class B is later freeing it[self].

It's safe to delete "this" as long as it's essentially the last operation in the method. In fact several professional level APIs do so (see ATL's CComObject implementation for an example).
The only danger is attempting to access any other member data after calling "delete this". This is certainly unsafe.

Delete this is perfectly legal as others have already mentioned. It is risky for one additional reason that hasn't been mentioned yet - you are assuming that the object has been allocated on the heap. This can be difficult to guarantee, although in the case of reference counting implementations isn't generally a problem.

but dont do it in the destructor !

As stated by others, delete this is a valid idiom but for it to be safe you have to ensure that the object is never instantiated on the stack.
One way to do this is to make both the constructor and the destructor private and enforce object creation through a class factory function which creates the the object on the heap and returns a pointer to it. The class factory can be a static member function or a friend function. Cleanup can then be done through a Delete() method on the object that does the "delete this". COM objects basically work this way except that in addition they are reference counted with the "delete this" occurring when the reference count is decremented to zero.

Yes. It should be perfectly fine. "This" is just a pointer. Any pointer will do for delete. The information on how to delete an object is contained in the heap records. This is how IUnknown::Release() is usually implemented in COM objects.

delete this can cause an issue when you have subclasses of the object you are deleting. Remember construction starts from top down and deletion starts from bottom up. So if delete this is in the middle of the hierarchy you basically lost all the objects below this particular class.
delete this comes very handy when you are implementing a reference counted object, an example of which is the COM classes.

Read for a similiar discussion. Your understanding is right in that it does work, is needed, and can be dangerous since you can't access this afterwards.

Legal Yes
Safe No

If you are inheriting from a base class and gave delete this in the base class function, using derived class pointer will cause a crash. E.g:
class Base
{
virtual void Release()
{
delete this;
}
}
class Derived : public Base
{
void Foo()
{
...
}
}
main()
{
Base *ptrDerived = new Derived();
ptrDerived->release();
ptrDerived->Foo() //Crash
}

Related

When should I provide a destructor for my class?

This seems like a rather trivial or at least common question, but I couldn't find a satisfying answer on google or on SO.
I'm not sure when I should implement a destructor for my class.
An obvious case is when the class wraps a connection to a file, and I want to make sure the connection is closed so I close it in the destructor.
But I want to know in general, how can I know if I should define a destructor. What guidelines are there that I can check to see if I should have a destructor in this class?
One such guideline I can think of, is if the class contains any member pointers. The default destructor would destory the pointers on deletion, but not the objects they're pointing at. So that should be the work of a user-defined destructor. E.g: (I'm a C++ newbie, so this code might not compile).
class MyContainer {
public:
MyContainer(int size) : data(new int[size]) { }
~MyContainer(){
delete [] data;
}
// .. stuff omitted
private:
int* data;
}
If I hadn't supplied that destructor, than destroying a MyContainer object would mean creating a leak, since all the data previously referenced by data wouldn't have been deleted.
But I have two questions:
1- Is this the only 'guideline'? I.e. define a destructor if the class has member pointers or if it's managing a resource? Or is there anything else?
2- Are there cases when I should not delete member pointers? What about references?
You need to define a destructor if the default destruction does not suffice. Of course, this just punts the question: what does the default destructor do? Well, it calls the destructors of each of the member variables, and that's it. If this is enough for you, you're good to go. If it's not, then you need to write a destructor.
The most common example is the case of allocating a pointer with new. A pointer (to any type) is a primitive, and the destructor just makes the pointer itself go away, without touching the pointed to memory. So the default destructor of a pointer does not have the right behavior for us (it will leak memory), hence we need a delete call in the destructor. Imagine now we change the raw pointer to a smart pointer. When the smart pointer is destroyed, it also calls the destructor of whatever its pointing to, and then frees the memory. So a smart pointer's destructor is sufficient.
By understanding the underlying reason behind the most common case, you can reason about less common cases. It's true that very often, if you're using smart pointers and std library containers, their destructors do the right thing and you don't need to write a destructor at all. But there are still exceptions.
Suppose you have a Logger class. This logger class is smart though, it buffers up a bunch of messages to Log, and then writes them out to a file only when the buffer reaches a certain size (it "flushes" the buffer). This can be more performant than just dumping everything to a file immediately. When the Logger is destroyed, you need to flush everything from the buffer regardless of whether it's full, so you'll probably want to write a destructor for it, even though its easy enough to implement Logger in terms of std::vector and std::string so that nothing leaks when its destroyed.
Edit: I didn't see question 2. The answer to question 2 is that you should not call delete if it is a non-owning pointer. In other words, if some other class or scope is solely responsible for cleaning up after this object, and you have the pointer "just to look", then do not call delete. The reason why is if you call delete and somebody else owns it, the pointer gets delete called on it twice:
struct A {
A(SomeObj * obj) : m_obj(obj){};
SomeObj * m_obj;
~A(){delete m_obj;};
}
SomeObj * obj = new SomeObj();
A a(obj);
delete obj; // bad!
In fact, arguably the guideline in c++11 is to NEVER call delete on a pointer. Why? Well, if you call delete on a pointer, it means you own it. And if you own it, there's no reason not to use a smart pointer, in particular unique_ptr is virtually the same speed and does this automatically, and is far more likely to be thread safe.
Further, furthermore (forgive me I'm getting really into this now), it's generally a bad idea to make non-owning views of objects (raw pointers or references) members of other objects. Why? Because, the object with the raw pointer may not have to worry about destroying the other object since it doesn't own it, but it has no way of knowing when it will be destroyed. The pointed to object could be destroyed while the object with the pointer is still alive:
struct A {
SomeObj * m_obj;
void func(){m_obj->doStuff();};
}
A a;
if(blah) {
SomeObj b;
a.m_obj = &b;
}
a.func() // bad!
Note that this only applies to member fields of objects. Passing a view of an object into a function (member or not) is safe, because the function is called in the enclosing scope of the object itself, so this is not an issue.
The harsh conclusion of all this is that unless you know what you're doing, you just shouldn't ever have raw pointers or references as member fields of objects.
Edit 2: I guess the overall conclusion (which is really nice!) is that in general, your classes should be written in such a way that they don't need destructors unless the destructors do something semantically meaningful. In my Logger example, the Logger has to be flushed, something important has to happen before destruction. You should not write (generally) classes that need to do trivial clean-up after their members, member variables should clean up after themselves.
A class needs a destructor when it "owns" a resource and is responsible for cleaning it up. The purpose of the destructor is not simply to make the class itself work properly, but to make the program as a whole work properly: If a resource needs to be cleaned up, something needs to do it, and so some object should take responsibility for the cleanup.
For instance, memory might need to be freed. A file handle might need to be closed. A network socket might need to be shut down. A graphics device might need to be released. These things will stay around if not explicitly destroyed, and so something needs to destroy them.
The purpose of a destructor is to tie a resource's lifetime to an object's, so that the resource goes away when the object goes away.
A Destructor is useful for when your classes contain Dynamically Allocated Memory. If your classes are simple and don't have 'DAM', then it's safe to not use a Destructor. In addition, read about the Rule Of Three. You should also add a copy constructor and an overloaded = operator if your class is going to have 'DAM'.
2) Do not worry about References. They work in a different way such as that it "Refers" to another variable (Which means they don't point to the memory).

Delegate method to remove self: possible problems? [duplicate]

This question already has answers here:
Is "delete this" allowed in C++?
(10 answers)
Closed 5 years ago.
In my initial basic tests it is perfectly safe to do so. However, it has struck me that attempting to manipulate this later in a function that deletes this could be a runtime error. Is this true, and is it normally safe to delete this? or are there only certain cases wherein it is safe?
delete this is legal and does what you would expect: it calls your class's destructor and free the underlying memory. After delete this returns, your this pointer value does not change, so it is now a dangling pointer that should not be dereferenced. That includes implicit dereferencing using the class's member variables.
It is usually found in reference-counted classes that, when the ref-count is decremented to 0, the DecrementRefCount()/Release()/whatever member function calls delete this.
delete this is typically considered very bad form for many reasons. It is easy to accidentally access member variables after delete this. Caller code might not realize your object has self-destructed.
Also, delete this is a "code smell" that your code might not have a symmetric strategy for object ownership (who allocates and who deletes). An object could not have allocated itself with new, so calling delete this means that class A is allocating an object, but class B is later freeing it[self].
It's safe to delete "this" as long as it's essentially the last operation in the method. In fact several professional level APIs do so (see ATL's CComObject implementation for an example).
The only danger is attempting to access any other member data after calling "delete this". This is certainly unsafe.
Delete this is perfectly legal as others have already mentioned. It is risky for one additional reason that hasn't been mentioned yet - you are assuming that the object has been allocated on the heap. This can be difficult to guarantee, although in the case of reference counting implementations isn't generally a problem.
but dont do it in the destructor !
As stated by others, delete this is a valid idiom but for it to be safe you have to ensure that the object is never instantiated on the stack.
One way to do this is to make both the constructor and the destructor private and enforce object creation through a class factory function which creates the the object on the heap and returns a pointer to it. The class factory can be a static member function or a friend function. Cleanup can then be done through a Delete() method on the object that does the "delete this". COM objects basically work this way except that in addition they are reference counted with the "delete this" occurring when the reference count is decremented to zero.
Yes. It should be perfectly fine. "This" is just a pointer. Any pointer will do for delete. The information on how to delete an object is contained in the heap records. This is how IUnknown::Release() is usually implemented in COM objects.
delete this can cause an issue when you have subclasses of the object you are deleting. Remember construction starts from top down and deletion starts from bottom up. So if delete this is in the middle of the hierarchy you basically lost all the objects below this particular class.
delete this comes very handy when you are implementing a reference counted object, an example of which is the COM classes.
Read for a similiar discussion. Your understanding is right in that it does work, is needed, and can be dangerous since you can't access this afterwards.
Legal Yes
Safe No
If you are inheriting from a base class and gave delete this in the base class function, using derived class pointer will cause a crash. E.g:
class Base
{
virtual void Release()
{
delete this;
}
}
class Derived : public Base
{
void Foo()
{
...
}
}
main()
{
Base *ptrDerived = new Derived();
ptrDerived->release();
ptrDerived->Foo() //Crash
}

Could an object deallocate its memory? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicates:
C++: Delete this?
Object-Oriented Suicide or delete this;
I'm learning C++ by reading the very good book C++ Primer and I'm learning how C++ deallocates memory by the delete keyword like C does with free. Java and Pascal do not have this mechanism for explcitly freeing memory. It could lead to errors in programs if they run for long time and variables are destroyed that are needed so it should not be trivialized.
In short I wonder if it's legal or advicable for instance in C++ for a variable to do this.delete() and delete itself. We mostly hear about freeing pointers in C and C++ and this is done with new free and delete keywords. Pascal also has pointers but Java has not. So in Java it should not be possible since you do not explicitly delete objects, C doesn't have objects so a struct couldn't free the memory it was allocated even if it was technically possible since C does not have objects and neither does Pascal.
So I suppose that leaves C++ for my question whether it is legal for an object to delete itself with something like this.delete()?
It's perfectly possible for an object to do delete this;.
However, after doing so, using thisis an undefined behaviour.
So, if you are very careful with was is done afterward, it's fine and legal for an object to "commit suicide" by doing delete this;
But, It's really not a good idea, especially because it means that your class should only be instanciated by new, as an allocation on te stack could cause the destructor to be called twice: by the delete this, and when going out of context.
The following example shows why it's not a good idea:
class A
{
public:
~A() { std::cout << "Destructor"; }
void foo() { delete this; }
};
int main()
{
{
A a;
a.foo(); // OK, a is deleted
} // Going out of context, the destructor is called again => undefined behavior
return 0;
}
this is a pointer. The proper syntax would be
delete this;
And yes, it's possible, but it renders your object and pointers to your object unusable.
See this for a good read.
In practice, using this technique is a code smell, unless you're absolutely sure what you're doing.
my question whether it is legal for an object to delete itself with something like this.delete()?
Technically, it is legal for an object to perform delete this. However, there is a number of hugely important caveats that are explained in the FAQ.
It is also important to understand that delete this solves a very narrow technical problem. It does not really solve any big-picture questions about memory management and garbage collection. One direction worthy of further study is the use of smart pointers in C++.
Although odd one use case would be say for a dialog box where the user clicks OK or whatever and this action causes the dialog box to delete itself but it is legal.
Of course the this pointer is no longer valid so you shouldn't try to use it.
It is entirely possible for an object to deallocate its own memory. However, it is very rarely used, for obvious reasons.
The most common usage is for implementing reference-counted memory management. When the caller invokes release() and the reference count hits zero, the object is deleted. Since this happens inside a member variable, it uses the this pointer to delete the instance (much in the same way you would call delete foo outside the object). For example:
int release()
{
OSAtomicDecrement32(&m_refCount);
if (m_refCount <= 0)
{
delete this;
}
return m_refCount;
}
(Note that the syntax you mention is not valid - delete is a keyword, not a method, and this is a pointer.)
There are several caveats to keep in mind though. Once this deletion has been called, the this pointer is no longer valid, nor are any of the data members. From that point onward, only non-instance references can be made (eg. to local variables, static methods and data, etc).
Another way for the object to delete its memory is using something called Resource Aquisition Is Initialisation RAII
With this method you do not new or delete the object. It's destructor automatically gets called when it leaves its scope.
i.e. You would use RAII in a function like:
void foo()
{
`Object a;`
`int i = a.SomeMethod();`
`// a's destructor automatically gets called when the function is out of scope`
}
Further Reading

Is "delete this" a bad idea? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is it safe to delete this?
I've been doing a little work on a class that's designed to act as a node in a linked list, and I figured I'd give the class its own deletion function as opposed to the managing class doing it. So basically it goes like this:
void Class::Delete() {
//Some cleanup code before deleting the object
delete this;
}
Now I've tested this and it appears to work fine, but I've had a problem in the past where objects have been in the middle of running code, been deleted, then obviously crashed the program by trying to use a no-longer-existing object.
Since "delete this" is right at the end of the function, it obviously exits the function and works fine, but is this sort of practice a bad idea at all? Could this ever blow up in my face if I'm not careful?
The FAQlite answers this quite well:
As long as you're careful, it's OK for
an object to commit suicide (delete
this).
Here's how I define "careful":
You must be absolutely 100% positive sure that this object was
allocated via new (not by new[], nor
by placement new, nor a local object
on the stack, nor a global, nor a
member of another object; but by plain
ordinary new).
You must be absolutely 100% positive sure that your member
function will be the last member
function invoked on this object.
You must be absolutely 100% positive sure that the rest of your
member function (after the delete this
line) doesn't touch any piece of this
object (including calling any other
member functions or touching any data
members).
You must be absolutely 100% positive sure that no one even touches
the this pointer itself after the
delete this line. In other words, you
must not examine it, compare it with
another pointer, compare it with NULL,
print it, cast it, do anything with
it.
Naturally the usual caveats apply in
cases where your this pointer is a
pointer to a base class when you don't
have a virtual destructor.
Basically, you need to take the same care as you do with deleteing any other pointer. However, there are more areas where things can go wrong with a member function committing suicide, compared with an explicitly-declared pointer.
Using delete this is a bad idea if one is not sure of the pitfalls & working around them.
Once you call delete this the object's destructor is going to be invoked and the dynamically allocated memory will be freed.
If the object was not allocated using new, it will be a Undefined behaviour.
If any of object's data members or virtual functions are accessed after delete this, the behaviour will be Undefined Behavior again.
Probably, It is best to avoid delete this given the above.
It's actually a frequent idiom, and about as safe as any delete. As
with all deletes, you have to ensure that no further code tries to
access the object, and you have to be sure that the object was
dynamically allocated. Typically, however, the latter is not a
problem, since the idiom is only relevant for objects which have a
lifetime determined by the semantics of the object, and such objects are
always allocated dynamically. Finding all of the pointers too the
object can be an issue (whether delete this is used or not); usually,
some form of the observer pattern will be used to notify all interested
parties that the object will cease to exist.
The idiomatic way of doing that in C++ is by putting the cleanup code in the destructor then let it be called automatically when you delete the object.
Class::~Class() {
do_cleanup();
}
void ManagingClass::deleteNode(Class* instance) {
delete instance; //here the destructor gets called and memory gets freed
}
There's a simple way of doing the same thing that doesn't involve undefined behavior:
void Class::Delete() {
//Some cleanup code before deleting the object
std::auto_ptr delete_me(this);
}

How do I *not* delete a member in a destructor?

I'd like the destructor of my class to delete the entire object except for one of the members, which is deleted elsewhere. First of all, is this totally unreasonable? Assuming it's not, how do I do this? I thought that created an destructor with an empty body would prevent all the members from being deleted (because the destructor wouldn't do anything), but that doesn't seem to be the case.
Short answer: You don't.
Longer answer: If the "member" is actually a pointer to some other allocation, you can arrange to not delete the other allocation.
But usually, if you allocated the other block in the constructor, you want to delete it in the destructor. Anything else will require careful handling of the "ownership" of the block in question. It will be a lot like memory management in plain c. Possible, but fraught with danger.
Good luck.
Depends on what you mean by "deleted". If they aren't in a smart pointer, and aren't explicitly deleted, then they aren't deleted. Members that are just part of the class:
class Bar {
//...
private:
Foo foo;
};
Aren't deleted by the destructor (because they weren't dynamically allocated), they are just destroyed. They "live" inside the class, so once it is destroyed, it's gone.
If you are looking the share "ownership" between two locations, what you want is a dynamically allocated shared_ptr:
#include <memory>
class Bar {
// ...
private:
std::tr1::shared_ptr<Foo> foo;
};
If the member is contained by value (not by pointer or by reference) then you can't prevent it from being deleted and you shouldn't want to.
If you want to delete it elsewhere instead, then make it contained by pointer or by reference.
class House
{
Door door; //contained by value, will be destroyed when the House is
}
class House
{
Door& door; //contained by reference, will not be destroyed when the House is
}
The code in the destructor is only to delete members that are dynamically allocated. The destruction of members is not optional, you can only control the deallocation of what you explicitly allocated before (with operator new).
What you want to do can be obtained using a shared_ptr, in which both your class and the external code share a pointer to the same external object. This way, only when all the pointers to that object go out of scope it will be deleted. But beware not to do circular references, shared_ptr has no "garbage collector" wisdom.
Of course you could use a regular pointer shared by those places, but this is in most cases a bad idea, prone to give you headaches about proper resource deallocation later.
First of all, if the member object is contained by value, it simply goes out of scope when the container object is destroyed, and you cannot prevent it from being deallocated automatically.
If, instead, it is indirectly referenced by your container object (for example with a pointer), you don't have to do anything in particular to not delete it. The destructor doesn't delete anything unless you explicitly write the code to do so.
As for the question whether this is unreasonable, I think it is not, in general, but you have to make clear (usually in the documentation, since C++ has no language support for this concept) what is the object that owns the member in question.
I think that in most cases you're asking for trouble if you don't destruct the entire object in the same action. It sounds like your class should have a clean up method for that member, which is called within the destructor. If for some reason the member has to be destroyed sooner, the method can return early.
First of all, is this totally
unreasonable?
I wouldn't say unreasonable, perhaps questionable.
It's perfectly valid for one class to own and therefore should take care of clean up, while at the same time having a reference or a pointer to that object in another class.
However, it might be questionable if the second class reall should have that pointer or not, I'd prefer to always use a get-method to retrieve that pointer whenever I need it, e.g. by calling a parent class or some resource manager.
If you have dynamically allocated memory for this member it is possible once you have shared the reference to this member before destroying the object and if you ensure the member is not destroyed in the object's destructor. However I think this practice isn't so reasonable.
When you talk about class members being deleted in the destructor, you have to make a distinction between members that are not pointers and those that are. Let's say you have a class like this:
class Foo
{
public:
Foo() {p = new int;}
~Foo(){}
private:
int a;
int *p;
};
This class has 2 data members: an integer a and a pointer to an integer p. When the destructor is called, the object is destroyed, meaning that the destructors for all its members are called. This happens even if the destructor's body is empty. In the case of a primitive type, like an integer, calling its destructor just means that the memory it occupies will be released. However, there is a catch when you destroy a pointer: whatever it points to does not get destroyed by default. For that you have to explicitly call delete.
So in our example, a will be destroyed when the destructor is called, and so will p, but not whatever p points to. If you wish to free the memory to which p points, the destructor for Foo should look like this:
~Foo() {delete p};
So, getting back to your question, all the members of your class which are not pointers will be destroyed no matter what, when the object's destructor is called. On the other hand, if you have members that are pointers, whatever they point to will not be destroyed, unless you specifically call delete for them in the destructor.
How come no one mentioned weak and strong pointers?
A strong pointer is a smart pointer that acts normally.
A weak pointer is a smart pointer that cannot delete itself unless all of the strong pointers are out of scope.
Strong pointer indicates ownership, a weak pointer indicates sharing.
Look at boost.shared_ptr and boost.weak_ptr and Loki's StrongPtr for implementations.
Also take a look at RAII. If you knew RAII you would have known the answer to this question yourself.
It is not unreasonable, but care should be taken to ensure that cleanup of any managed resources is handled implicitly.
(The first managed resource that people generally worry about is memory, but anything that can leak - memory, file handles, IDispatch pointers - should have code which handles the cleanup implicitly).
For managed resources shared by multiple objects (almost certainly the case if "this object" is supposed to have a pointer to something that gets cleaned up by "that object"), you are normally needing either a "reference counted pointer" to manage the object or a "weak pointer", depending on your lifetime requirements.
For managed resources which are not shared (and in particular those that need to be managed properly when exceptions can be thrown), then an auto_ptr or other variant may be more suitable.
The Scott Meyers Effective C++ books were a reasonable starting point for learning about smart pointers, but in practice you should probably just grab a vetted library like Boost and let somebody else worry about getting the obscure corner cases (like what happens if a constructor throws an exception?) right.
This is possible but basically as #dmckee said it is then a ownership issue. If that is the case may be you can go for refcounting. i.e.
class A
{
RefObj* obj;
A()
{
obj = new RefObj;
}
~A()
{
obj->ReleaseRef();
}
}
RefObj
{
int m_iRefCounter;
RefObj()
{
m_iRefCounter = 1;
}
AddRef()
{
m_iRefCounter++;
}
ReleaseRef()
{
m_iRefCounter--
if(m_iRefCounter == 0)
{
delete this;
}
}
}
}