Destructors and the delete() method in C++ - 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.

Related

Do you call delete in destructor in C++?

Let say you have a class like this
class Level
{
public:
Level(std::string);
~Level();
private:
Bitmap* map;
}
and in the class you had this
Level::Level(std::string)
{
map = new Bitmap(path);
}
Was wondering do can you call
Level::~Level()
{
delete map;
}
As I was worried about if the class goes out of scope and I haven't deleted map. Then, wouldn't that cause a memory leak. Do I have to manually call to delete map. As I get crash if I call delete in the constructor in my program.
Like I could add a method to Level called say destroy map where I delete map. But, was wondering why I can't add delete into the destructor.
When the Level object goes out of scope, its destructor will be called, so deallocation of memory is useful because that memory is no longer needed. You can also use a unique_ptr, whereby memory-deallocation performed automatically.
This is why destructors stand for. Destructor is explicitly called when your object goes out of scope (memory residing on the stack objects) or when delete is called ( for dynamically allocated objects), so that the memory the object kept would be released. If you want to release member objects memory when destroyed, you can call the destructors of each object using delete (or delete[] for arrays). It is better that you use smart pointers, to avoid unintentional memory leaks and to ensure the memory is freed correctly in all cases, as they use RAII concept (RAII and smart pointers in C++).
Answers already have pointed out that you can trust your destructor to be called when your object goes out of scope. I won't reiterate that. I just wanted to point out that there is no need to allocate your Bitmap with new (unless you were using custom memory allocators, which is not the case here). You can construct it with an initialiser list:
class Level
{
public:
Level(std::string);
private:
Bitmap map;
};
Level::Level(std::string)
: map(path)
{
}
Now it has automatic scope and you don't have to worry about your destructor.
That's basically right.
However:
You need to make sure you create a copy constructor and assignment operator too, if you are managing memory this way. (That's where your crash comes from.)
An alternative, the best way, is to use RAII and store not a raw pointer but a scoped or automatic pointer. Or even just a directly encapsulated object! Then you don't need the delete at all.
As I was worried about if the class goes out of scope and I haven't deleted map. Then, wouldn't that cause a memory leak.
You're right - you should delete map exactly as your code does. But, you should also make your object non-copyable (derive from boost or C++11 noncopyable base classes, or add a private declaration (with no definition/implementation) of the operator= copy assignment and copy constructor. Otherwise, if you (deliberately or accidentally or incidentally - e.g. when storing your object in a container that sometimes copies it around, such as a std::vector) copy your object, then the first copy destructored will delete the map, any other copy that tries to use it will likely crash, and any other copy's destructor that also tries to delete it will also have undefined behaviour.
Do I have to manually call to delete map.
Yes, in your code you do.
A better alternative is to use a smart pointer whose own destructor will delete the pointed-to object.
As I get crash if I call delete in the constructor in my program.
Well, if you call delete after the new, then the constructor won't crash, but you wouldn't have a map object to use after the constructor returns, and if you then try to delete it again in the destructor the you get undefined behaviour which may well manifest as a crash.
If you want to delete the map earlier than the destructor sometimes, you can set the pointer to NULL so that a future delete will do nothing safely. You should then check for NULL before trying to use the map.
Like I could add a method to Level called say destroy map where I delete map. But, was wondering why I can't add delete into the destructor.
As above, you can have destroy_map, but it must coordinate with the destructor.
When there's no compelling reason to do otherwise, it's better to make the map member data, not storing it by reference. When a pointer is useful, use a smart pointer if at all possible. If you want to implement explicit manual memory management, be wary of the issues above.
This is an unusual way to do it. Normally, an object's lifetime is determined by factors outside of the object.
But in fact MFC used to (still does?) do exactly this when a Window is being destroyed. (In response to WM_NCDESTROY, I believe.) This ensures you don't have the Window instances leaking memory after the window is gone.
So I would say it is valid in some cases. You might call it class suicide!

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.

How to properly define destructor

I am relatively new to C++ (and programming in general) so please forgive me if the question is not perfectly clear immediately.
What I have is a program in which a certain number of objects of a internally defined class [let's call this "class1"] are created.
The program works perfectly fine and the objects do what they should.
The problem that I am currently trying to solve is the following: these objects are not destroyed (and thus memory is not de-allocated) until the program exits, but I need that memory earlier.
Among the other members of the class there are objects of other internally defined classes (who also have members that are objects of a third class).
My question is the following: how do I properly define a destructor for the objects of "class1" so that all the data is cancelled and the memory deallocated?
I found out (probably this was obvious for you already) that a destructor like
class1::~class1(void) {
}
won't work (I defined similar destructors for all internally defined classes).
Reading around I understood that my mistake could be that that is a destructor that does nothing. How do I solve this?
Thanks to anyone who will answer/help/comment.
Federico
In C++ you need to free the memory manually. There's no garbage collector. You obviously need to free the memory manually inside your destructor. If you allocated the memory using new, you need to use delete for each resource you allocated with new inside the deconstructor, for example:
class1::~class1(void)
{
delete resource1;
delete resource2;
etc...
}
If you are allocating memory dynamically you need to free it in destructor, but better solution would be to use some smart pointer to hold dynamic data - std::auto_ptr or std::shared_ptr. Then you will not need to explicitly free memory - this will be done automatically in smart pointer destructor.
First you should try to allocate your objects on the stack:
Object obj;
so you don't have to worry about memory allocation. The disadvantage is that the object life is limited to the current scope.
If that's not good for you, you should consider using smart pointers. If that's not an option use new / delete to create / destroy your objects. But you have to be careful, every new should lead to a delete at some point in time..
Memory on stack
If there is no heap-allocated object inside your class, there is no need for you to explicitly define the destructor of your class. The compiler-generated one should handle the job quite well, i.e., call destructors for base class objects and member objects, etc.
Memory on heap - manual memory management
If there is any heap-allocated objects inside your class, you need manually deallocate them in your destructor. Make sure you have them deallocated properly at all possible exit points, e.g., handle exceptions and deallocate resources.
Memory on heap - RAII
Alternatively, you may use some well-defined RAII class to handle the resource management for you automatically, e.g., scoped_ptr, scoped_array in Boost, shared_ptr in STL, etc.

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.

Destructors in C++

Does the destructor deallocate memory assigned to the object which it belongs to or is it just called so that it can perform some last minute housekeeping before the object is deallocated by the compiler?
The 'compiler' doesn't delete anything. It creates code that does things at runtime.
When you write delete somePointer; the compiler, in essence, writes:
if ( has_virtual_destructor( * somePointer ) ) {
// virtual dispatch to a compiler-generated function
dynamic_cast< true_dynamic_type * >(somePointer)->destroy_dynamic_type();
/* contents of true_dynamic_type::destroy_dynamic_type() {
this->~true_dynamic_type();
operator delete( this); // executed within class context
} */
} else {
somePointer->~ClassName();
operator delete(somePointer);
}
In other words, the destructor gets called, and then operator delete gets called to free the storage.
If the destructor is virtual, a virtual dispatch is used to perform the entire operation on the object in its most-derived form. A common way of implementing this is to add hidden arguments to every virtual destructor.
Note that the top-level if statement isn't really part of the generated code; the compiler makes that decision at compile-time.
The destructor is called to allow the object to perform cleanup as well as to destroy any other objects the object itself has created.
The OS will deal with deallocating the object itself after finishing the destructor.
1) destructor doesn't belong to object, it belongs to class
2) It calls destructor for all the user defined types (class objects) within its class.
3) Cleanup is optional activity which is done only if it is really required
The memory is deallocated right after the destructor function exits and before execution returns to the "delete" call or point where an object instance goes out of scope. In theory it is possible to set up a different memory manager to handle new and delete, but that would be an explicit change of the default behavior.
More specifically, nobody but the programmer deallocates memory in C++. If the object is on the stack, it is resident in the memory space of the program, and takes space during the lifetime of the program. If it is on the heap, whoever created the object is responsible for deallocating it. Thats what delete does. This brings us to the destructor - if you create objects in your class, the destructor allows you to delete them as the class leaves scope. It lets you "turn out the lights as you leave".
Destructors automatically call the destructors on member variables of the object being destroyed. Those destructors may or may not free up memory. However, a pointer has no destructor, or if you prefer, a pointer's destructor does nothing. It does not free the memory that it points to. If an object contains a pointer to an object obtained from "new" or "malloc," it is up to the programmer of that object to make the destructor do the right thing. You should program your destructor to "delete" or "free" the memory if it is conceptually part of the object being destructed. For example, a "vector" object typically obtains memory from the heap, because the amount of memory required is not generally known at compile time. That memory is conceptually part of the vector object, and thus the programmer of the vector class must call "delete" on it in the destructor. Standard Template Library classes like std::vector do it properly.
On the other hand, some objects contain references to other objects. A dictionary or index will contain references (pointers) to objects that are not conceptually part of them. That memory must not be freed by the destructor. (If you remove your phone number from the phone book, you do not want your phone to automatically disappear.)
There are exceptions that the novice need not be concerned with at first. One is when the object and its containers are programmed to use reference-counting, and the referenced object is not really freed until the last object referring to it lets it go. Another exception is in the case of "placement new."