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."
Related
So I dynamically allocated a class object with this code:
void Inventory::createNewInventoryItem(std::string itemName, unsigned int maxQuantity, unsigned int orderThreshold, double price)
{
InventoryItems* newItem = new InventoryItems;
newItem->createInventoryItem(itemName, maxQuantity, orderThreshold, price);
m_inventory.push_back(newItem);
}
Which is stored in this vector: std::vector<InventoryItems*> m_inventory;
Then once the object is done being used deleteInventoryItem is called, which is defined as:
void Inventory::deleteInventoryItem(int posInVector)
{
m_inventory.at(posInVector)->~InventoryItems();
m_inventory.erase(m_inventory.begin() + posInVector);
}
My question is: Will this deleteInventoryItem function successfully free up the memory used by the dynamic allocation in createNewInventoryItem? (This ties into my confusion around if delete[] is needed when a class deconstructor is called)
Sorry for the not "Mission critical" question, just trying to make sure I'm not continuing bad practices as I'm really trying to program as perfectly as I could...
Will this deleteInventoryItem function successfully free up the memory used by the dynamic allocation in createNewInventoryItem?
No, your code does leak memory. What you do here,
m_inventory.at(posInVector)->~InventoryItems();
is explicitly calling the destructor of the container element. This does clean up any resources held by the specific object, but not the memory resource that hosts the object itself. It is very, very rare that you have to manually call the destructor of an object (the only situation I can think of is using placement new, and you very rarely need that).
What you could have done is using delete to both clean up the memory and invoke the destructor of the element being erased. But as a much safer alternative for this manual memory management, I would advise you to choose one the following two options
If the object that is supposed to be stored in the container fine with being copied by value (i.e. not a polymorphic type and you want to store base class references), just store it by value:
std::vector<InventoryItems> myData;
Otherwise, store a std::unique_ptr which takes care of all the memory managent for you:
std::vector<std::unique_ptr<InventoryItems>> myData;
No it will memory-leak. You are obviously calling the destructor but do not call delete which is the counterpart of new. The new followed by a type allocates memory first then calls implicitly the destructor. The delete operator also does two things, first calling the destructor, then deallocate the memory.
There is rarely a need for explicitly calling the destructor, specifically for cleaning up instances created through the new placement syntax., and not calling ~ it in this case will lead to leaks if the instance contains hold dynamically bound resources via members or base class(es).
As a rule of thumb, keep these pairs in mind:
obj = new Class; needs delete obj;
obj = new (buffer) Class needs obj->~Class();
array = new Class[count]; needs delete [] array;
... and, as the most important in the collection, automatic objects:
Class obj; needs (nothing) but the end of the enclosing scope
The last "pair" shows an implicit call to (default) constructor (it could be any other constructor provided by the Class definition) and ends (at the closing brace) with an implicit call of the destructor, which, by the way, the reason for the C++ language to limit the destructors of a class to at maximum one: The compiler depends on this uniqueness to be able to automatically close scopes. This very automatism also forms the basis for std::unique_ptr and std::shared_ptr.
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.
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.
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!
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.