How does "delete" reclaim memory? - c++

I would like to concentrate on what happens when we say delete ptr. I know that a destructor of our class is called and then the amount of space new allocated is reclaimed.
If our object has other pointers etc, would that be reclaimed as well or is it up to the definition of our constructor to do so?

The destructor is responsible for clearing up all the resources an object owns. That includes calling delete on pointers that require it. If your destructor does not do this, then you will get a memory leak.
If your objects has members with automatic storage duration, then the destructors of those members are called automatically. This is the foundation of RAII.

If the object that you delete has pointers to other objects or blocks of memory then no, those will not be automatically deleted if your object is deleted. You have to take care of that yourself; the appropriate place to do that is most likely in the destructor of the class of your object.
If you don't deallocate all memory properly then your program has a memory leak.

It's up to the definition of your destructor (not constructor).

Related

Why call the default destructor of an object before freeing the memory allocated to that object?

I seen some code do the following:
ExampleObject< T > * eo = const_cast< ExampleObject< T > * >(this);
eo->~ExampleObject();
free( eo );
The ExampleObject in question has been allocated using placement new.
There is no user-defined destructor supplied, so it's the compiler supplied default destructor being used here, I think.
I don't understand why it is necessary to call the destructor here. If we had a user-defined destructor that de-allocated memory for some of it's class members I could understand the usage here, but in the case of a default destructor I don't know why we'd do this.
What does the default destructor of an object do, that would require us to call it before freeing the allocated memory for the object?
What does the default destructor of an object do
It calls the destructors, if any, for the object's data members.
that would require us to call it before freeing the allocated memory for the object?
The ONLY time a destructor should ever be called explicitly is when the object has been constructed using placement-new inside a pre-existing memory block. Using placement-new separates the tasks of object construction/destruction from memory allocation/deallocation, so you need to construct and destruct an object explicitly, but you don't have to allocate/deallocate its memory block, you can manage that however you want elsewhere.
If you do not use placement-new to construct the object, but rather allocate + construct the object using new instead, then you must destruct + deallocate the object using delete (and you should preferably use a smart pointer, std:unique_ptr or std::shared_ptr, to handle that for you).
If you do not construct the object using any form of new, then DO NOT try to destruct the object manually at all. The object is in automatic storage and the compiler will manage it for you.
The C allocation functions know nothing about C++ objects. Unlike new and delete that allocate the memory needed and call the constructor/destructor, all The C functions do is allocate/deallocate a suitably sized amount of memory that you can use.
So when you use the C functions, you have to call the allocation function to get the memory, call placement new on it to actually construct the object in the memory (this is required to actually have an object of that type). Then, when you are done with it you need to destroy the object by manually calling the destructor (you need to do this so the objects lifetime properly ends) and then pass the pointer to free so the memory can be released.
This is why you should not be using *alloc and free in C++. They require a lot of extra work and are not type safe.
A default destructor function is called automatically when the object goes out of scope:
The function ends
The program ends
A block containing local variables ends
A delete operator is called
Default destructor always invokes the destructors of its member objects (not for member variables that are pointers to objects). If we allocate memory dynamically it should be handled by us, otherwise default destructor clears the local variables.
If we do not write our own destructor in class, the compiler creates a default destructor for us. The default destructor works fine unless we have dynamically allocated memory or pointer in class.
When a class contains a pointer to memory allocated in class, we should write a destructor to release memory before the class instance is destroyed. This must be done to avoid memory leak.

Destructors and the delete() method in C++

So I added a destructor function to a class in C++.
class object { ~object() };
And declared an object with the new method, thereby allocating it on the heap
object *pointer = new object;
Do I still need to use the
delete(object);
method at the end of the program? (Isn't the destructor already responsible for exactly this?)
You still must call delete(object). Destructor is responsible for how to delete an object and delete(object) is responsible for when to delete it. But in modern C++ usage of naked pointers is considered a really bad practice. You should consider using smart pointers, such as std::unique_ptr for managing memory.
You have 2 different kinds of memory. The stack and the heap.
Everything on the stack deletes itself when you go out of scope (one of the steps of deletion is calling the destructor)
Everything which is on the heap (you call malloc, new, etc) you have to delete explicitly by yourself (which will then result in the destructor being called).
Smart pointers like unique_ptr / shared_ptr are a modern c++ way to get rid of the manual deletion on heap objects and to make sure they get deleted when the objects are not needed anymore.
Destructors are a way of customizing the clean-up process (add logging, provide cleanup as per rule of three/five, etc.). You still need to delete, otherwise you'll have a memory leak.
That being said, it's frowned-upon and considered a bad practice to write code that actially needs news and deletes (especially the latter). If you need to store an object on the heap, use unique_ptr/shared_ptr or a container like vector.
If you have the time, I suggest you watch Herb Sutter's talk from C++Con 2016: Leak-Freedom in C++ for guidance.
The destructor gets called when the objects lifetime is over. For heap allocated objects this means when you delete them.
So a call to
delete(object);
calls your descructor and frees the allocated memory.
Yes, you must need Delete method.
Default destructors call destructors of member objects, but do NOT delete pointers to objects. Thus, You need to write destructors that explicitly call delete. Like,
delete pointer;
Do I still need to use the delete(object); method at the end of the program?
Yes.
Isn't the destructor already responsible for exactly this?
No.
Your delete ptr; is what invokes that destructor. If you hadn't declared a destructor, one would have been declared for you, so that made no difference.
You don't need to write delete ptr; when your object has automatic storage duration (very loosely: "when you didn't create it with new"), because then the equivalent is done for you.
But in both cases the destructor is called.
A new and a delete expression (which are not the new and delete operators) are invoking two calls:
new:
1) call the operator new for memory allocation
2) invoke the appropriate constructor
delete:
1) invoke the destructor
2) call the operator delete for memory deallocation
Hence you have to pair any new with a delete, to avoid resource (memory) leaks.
However, object construction and destruction does not require new and delete.

C++ Memory Management: Who is responsible

Suppose I am writing a C++ class. The class has the following fields:
An integer.
a C++ string
dynamically resizable integer array and a pointer to it.
In the destructor, I know I have to delete anything that I had earlier claimed by calling new. In this case, I know I have to free the space I used for the int array. What about the string's memory? I know I'm not responsible for releasing its memory, because I didn't call new to allocate it, but how does it get freed? When does C++ call its destructor?
What about the string's memory? I know I'm not responsible for releasing its memory, because I didn't call new to allocate it, but how does it get freed?
Your class's destructor implicitly calls std::string's destructor which in turn handles the freeing of its own resources. Nothing else to worry.
When does C++ call its destructor?
When your class' object's destructor is called. That means when that object goes out of scope or delete has been called on a pointer to it when it has been created by new.
I somehow understand your problem. You may think that new recursively news the members of your class. No. It doesn't do it that way. Unless your class itself does new on the member variables will you need to call delete on them.
Destructors of member variables are automatically called once the instance destructor has completed.
That memory is reclaimed when the variable goes out of scope.

C++ destructor: when the memory gets freed?

If I delete an object which causes its destructor to be called, does the memory get freed before or after the destructor has finished doing whatever there is in the function?
Memory is only freed once the least derived class subobject has been destroyed. So if you have:
class Base {
};
class Derived : public Base {
public:
~Derived();
};
then first Derived is destroyed, then Base is destroyed and only then memory is deallocated.
Decompose delete into what it is actually doing and it is relatively clear to see when the memory is deleted. So a statement like this:
delete some_ptr;
Is roughly equivalent to this pseudo-code:
some_ptr->~some_ptr();
free( some_ptr );
So the memory is freed after the call to the destructor. Exactly what the destructor does is not determined by the delete operator, but rather the definition of the class. Usually it does local cleanup and ensures that its base class destructors are also called.
It is important to realize that freeing the memory is not actually part of the destructor. It is the delete operator which frees the memory.
Note that the free function in pseudo-code is actually one of the operator delete() functions, either for the deleted class, or global. That actually frees up the memory.
The memory gets freed after the destructor has finished. Otherwise, accessing member variables inside the destructor would cause segfaults.
operator delete is called after destructor, but when the memory is freed is up to used allocator
I would think that the memory is freed after the destructor function itself has finished executing. I know that when an exception is caught, the destructor to the object is not called until the object itself goes out of scope.
In C++, destruction is about executing some code using the data available in the object. This code is arbitrary.
Free'ing the memory is a low level handling, hidden by the delete operator in general, that should never be called prior to calls to the destructor.
This is best summarized by the Allocator interface:
allocate and deallocate are used to manipulate raw memory
construct and destroy are used to call the constructors and destructors of the objects
It is precised that construct, destroy and deallocate should only be executed on memory previously allocated by that allocator. It also precises that destroy does not deallocate the memory, and that a subsequent call to deallocate will be necessary.
Note that this is a low-level interface, which allow destroying an object and reusing the freed space to construct another in place.

Deleting an object

First, when you want to free the memory assigned to an object in C++, which one is preferred? Explicitly calling destructor or using delete?
Object* object = new Object(...);
...
delete object;
OR
object->~Object();
Second, does the delete operator call the destructor implicitly?
delete implicitly calls the destructor, you don't need (more precisely: shouldn't) call it directly.
A destructor will never release the memory occupied by the object (It may reside on the stack, not on the heap, and the object has no way of knowing -- however, the destructor will delete any memory allocated by the object's components).
In order to free the memory of an object allocated on the heap, you must call delete.
When you write your own class, C++ will provide a default destructor to free the memory allocated by component objects (such as a QString that is a member of your class), but if you explicitly allocate memory (or other resources) in your constructor, be sure to provide a destructor that will explicitly free these resources.
Another general rule regarding your own classes: If you mark any methods virtual, your destructor should be virtual, as well (even if you rely on the default destructor), so that the correct destructor is called for any classes derived from yours.
I prefer neither.
An explicit destructor call is needed very, very rarely, only when you are dissociating memory allocation from object lifetime. You might need it if implementing a custom container class.
An explicit delete is, potentially, a legitimate way to destroy an object dynamically created with a new expression but it should be unnecessary in most application code as it signals a place where potential mismatches between new and delete might occur and areas with potential exception safety issues.
Where an object lifetime is constrained to a block a local variable should normally be preferred as the memory allocation overhead is usually lower and the object will automatically be cleaned up correctly however the block is exited.
{
// ...
Object object( ... );
} // object destructor run, however this block is exited.
If there is some reason that this can't be need (e.g. the object has an excessive static size) or it's lifetime can't be matched to a particular scope, then usually some sort of smart pointer should be used to manage the objects lifetime. The most basic smart pointer which is available in standard C++ is std::auto_ptr which can be used for block scoped dynamically allocated objects but has 'surprising' behaviour on copy and assignment. Something like tr1::shared_ptr (or boost::shared_ptr) are common alternatives where shared ownership is needed.
{
std::auto_ptr<Object> object(new Object(...));
// ...
} // *object destructor run, however this block is exited.
delete is preferred. Just calling the destructor does not free the memory allocated by the new.
Use delete. It calls the objects destructor and then frees allocated memory.
Also, it's not a deconstructor, but a destructor.
Normally you never want to explicitly call the destructor. Just use delete.
Invoking delete will invoke the destructor and then release the memory.
Invoke the destructor explicitly will only invoke the destructor, and not release the memory.
You should therefore almost always call delete: except when you want to invoke the destructor without releasing the memory, e.g. because you constructed the object using placement new.
You should never call the destructor yourself. delete will call it for you
Something else to consider:
since delete calls the destructor internally, it’s an error to do both, i.e. calling the destructor and then delete. So the following code:
Foo* px = new Foo;
// …
px->~Foo();
delete px;
Will produce a nasty bug. Depending on the actions taken in the actual destructor, this may go unnoticed for quite some time, since the compiler actually allows this code. This may lead to subtle, hard to discover bugs.
You should use delete
http://www.parashift.com/c++-faq-lite/dtors.html
When you are using dynamic memory allocation to create the object at that time you can use the delete operator to destroy/delete the object but when you are not using DMA at that time trying to delete an object using delete operator throws error. One way to handle this situation is, writing your own destructor explicitly and calling the destructor using the object to destroy it.