Let consider this code:
#include <iostream>
class A{
public:
~A() {}
};
int main(){
A *p = new A();
p->~A();
return 0;
}
I would like to know if the memory of the object A pointed by p is freed or we must to call delete p;
The memory was not freed. The destructor destroys the object but does not free the memory. How could it? You can destroy objects that are dynamically allocated, are on the stack, are globals, and so on. The destructor has no idea what is needed, if anything, to release the memory.
Memory was allocated using operator new and will be freed (deallocated) using operator delete, not your object's destructor.
We should not confuse the object lifetime with dynamic memory management.
It is not A's destructor role to free the allocated memory and it should not be called explicitly. It is simply a member function that gets called when your object gets destroyed. And it will get destroyed after you call the delete.
Replace:
p->~A();
with:
delete p;
Now your objects gets destroyed and the allocated memory gets deallocated.
There is no difference between calling destructor or any other member function, except one thing - you should not do it, unless you want to separate object allocation from its construction and destruction.
Related
What is the difference between the destruction of an object and deletion in C++? In OOP, when an object goes out of the scope, the destructor is called, and when dynamically allocating memory we have to use the delete keyword inside the destructor. So what does it mean for an object to be destroyed or deleted?
A destructor is a special method for a class. It is called whenever an object goes out of scope, or someone calls it explicitly.
An example where an objects destructor is called, but no delete:
struct MyObject
{
MyObject() { std::cout << "default constructor"; }
~MyObject() { std::cout << "destructor"; }
void doWork() {};
}
int main()
{
{
MyObject object; //constructor is called and memory allocated for the object on the stack
object.doWork();
} //at the end of scope, the destructor of MyObject is called, and the stack memory is "released"
// object is not longer available and stack memory is free
}
An example when scope does not help you:
int main()
{
{
MyObject* object_ptr = new MyObject; //constructor is called and memory allocated on the heap. The pointer_ptr object
object_ptr->doWork();
} //at the end of scope the object_ptr is removed from the stack, but the destructor for the MyObject is not called!
// object_ptr is no longer available.
}
For the above example, we have an issue with the dynamically allocated memory. We explicitly call the destructor of the object we are pointing to by calling delete (and freeing the memory where MyObject is residing!):
int main()
{
{
MyObject* object_ptr = new MyObject; //constructor is called and memory allocated on the heap. The pointer_ptr object
object_ptr->doWork();
delete object_ptr; // destructor of MyObject is called and memory freed.
// object_ptr is still usable here, but it is pointing at an destroyed object, so don't use it! (unless you redirect it)
}
}
So delete is for managing the dynamic memory, but the destructor is a method of the class itself, which is always called when the object is getting freed from the memory (stack or heap). The destructor is called when freeing the memory for the object, so that if the object itself handles memory, is has time to release that memory. That's why smart pointers are good:
int main()
{
{
std::unique_ptr<MyObject> object_ptr = std::make_unique<MyObject>(); //constructor is called and memory allocated on the heap. The pointer_ptr object
object_ptr->doWork();
} //destructor for std::unique_ptr<MyObject> is called, which in turn calls delete on the object it is pointing at, which calls the destructor of that object!
}
There are multiple ways for memory allocation some of them are:
Automatic memory allocation :
In this case ,the variables defined inside a scope ,for example functions, are automatic allocated, and is usually stored on the stack. You have a limited control over the lifetime of this memory. E.g: automatic variables in a function are only there until the function finishes, then when going out of that scope, their destructors are called automatically i.e. you must not call delete to free the memory reserved for that object.
Dynamic memory allocation :
In this case , the variables defined inside a scope ,for example functions, are dynamically allocated. You control the size and the lifetime of these memory locations. If you don't free the reserved memory (delete it), the allocated memory is still valid and accessible, even though the function terminated (went out of scope) and in this case you'll have memory leakage, which may cause the program to crash. So the object should be delete explicitly which in turn will call the destructor for that object.
In the same way that a constructor is only part of the process of creating an object, invoking the destructor is just part of the process of destroying an object. It is a place where special clean-up code can go, like closing file handles or destroying other, indirectly-owned objects.
delete is the way you trigger the deletion of a dynamically allocated object. Other types of object are deleted automatically when they go out of scope. This keyword will clean up memory and more abstractly end the object's lifetime so that the compiler knows it doesn't conceptually "exist" any more.
You generally don't call the destructor manually, as it is usually insufficient for safely ending the lifetime of an object on its own. However, doing so is useful when you're taking super-fine-grained control over objects' existences, with (for example) placement new: then, it can be sufficient. But this is a special case.
When an object is destroyed it's destructor is called. A pointer to a dynamically allocated memory can be deleted, objects themselves can't be deleted (unless you think of a pointer as a kind of object).
Either of these actions can have knock on effects that cause the other action to happen (or more instances of the same action). For instance if you delete a pointer to an object, then the objects destructor will be called (if it has one) and it's destructor may cause other pointers to be deleted and other objects to be destroyed.
Basically destructor is about the death of objects and deletion is about the freeing of dynamically allocated memory, but the two actions are often intertwined.
I studding C++ concept. I'm confused in constructor and Destractor concept. Destructor will be invoked implicitly by the compiler upon exit from the program. But in my program, only constructor called.
#include <iostream>
using namespace std;
class A
{
int i;
public:
A()
{
cout<<"Constructor call"<<endl;
}
~A()
{
cout<<"Destructtor call"<<endl;
}
};
int main()
{
A *a = new A();
}
Output:
Constructor call
So, I have question : Why destructor not call implicit by the compiler upon exit program?
Why destructor not call implicit by the compiler upon exit program?
Because dynamically allocated objects are not destroyed automatically. That is how the language has been specified. Tracking the destruction of dynamic objects would require runtime / memory overhead.
Solution: Do not leak dynamically allocated objects.
There are 2 "types" of variable lifetime in C++. Dynamic and automatic.
Automatic is something like :
void foo()
{
int i; // automatic storage
} // destroys i
Here, i will be destructed the moment it leaves scope (after foo returns). You can check this for yourself by making your object have an automatic lifetime:
int main()
{
A a; // calls A's constructor and allocates memory.
} //calls A's destructor and frees the memory used.
You'll see that both the constructor and the destructor will get called.
The second form is dynamically allocated memory. You can dynamically allocate memory by using new (like you did) and free that memory by using delete. The compiler won't do this for you.
This means that, to destruct your object you have to call delete explicitly yourself:
int main()
{
A* a = new A();
delete a; // calls A's destructor and frees the memory used.
}
If you do not call delete (like your code) then the moment the program leaves main the pointer a is destroyed and now we have a piece of memory that nothing can reach and thus nobody can clean up (with delete) which means you're leaking memory.
However, modern operating systems reclaim all memory used by the program automatically the moment the program ends so at this point it won't matter too much. This does mean your destructor won't be called as you've just witnessed.
Dynamically allocated memory allows you to do some nifty tricks like controlling the lifetime of your objects to the point where you want to destroy them explicitly yourself with delete. The problem with using new and delete is that it's so easy to forget a single delete and your program will already leak memory, which is why it's advised to stay away from this way of allocation.
If for some reason you absolutely need dynamic lifetime then use a smart pointer like std::unique_ptr that will call new and delete for you the moment it goes out of scope.
You create the object dynamically with new. The destructor will only be called when the objected is deleted with delete.
To prevent memory leaks, you could/should use smart pointers like unique_ptr.
In any case, the memory itself will of course be released when the process ends.
The destructor is never called in your code because the object is never destroyed.
You dynamically allocate the A object and you never deallocate it. Add delete a; into main() and you'll see the destructor in action:
int main()
{
A *a = new A();
delete a;
return 0;
}
In your main function, you create a pointer variable that you must delete it by delete a at end of main function.
Because you have a memory leak. You dynamically created an object with new, promising that you would manage the lifetime of the object and clean it up later with delete. Then you broke that promise.
If you create an object in the usual fashion:
A a;
then it will be destroyed automatically for you.
I am learning C++ in an online class, currently discussing pointers and memory leaks.
In the course it was told that when a function body ends all local variables are destroyed (in reverse order to which they were declared).
What i'm trying to understand is whether this code leaks memory or not:
void function()
{
TestClass *p = new TestClass();
}
As it seems, it does, but i am not sure why the pointer "p" is not being dereferenced to its heap address and the data there is deleted once the function scope exits.
Definitely it will leak memory. when a function body ends all local variables are destroyed indicates to the variables that are created in stack, not heap. If you allocate memory in heap, you have to release it when done.
Another thing is your concept about dereference is wrong. Dereference means using the object pointed by a pointer, not freeing the memory of the pointer, which is called Deallocation
The pointer itself will be destroyed as it is allocated in stack, but the data which p points to will leak. If you write
TestClass tc;
TestClass *p = &tc;
then all the objects will be created in stack and destroyed, but using new forces to use the memory from heap. You have to use delete to release it.
new is used to allocate memory for a C++ class object in heap, the object's constructor is called after the memory is allocated.
The delete operator must be used to deallocate the memory allocated with the new operator, otherwise there is a memory leak.
delete *p;
I have a C++ class, MyClass. It contains a constructor, destructor and an int pointer private: int *MyPtr;.
Somewhere, I allocate dynamically a MyClass Object:
MyClass *my = new MyClass(); //...
Then I call delete my;
Should MyClass have a destructor which uses something like delete MyPtr? Or is that MyPtr destroyed when I call delete my?
If you allocated MyPtr insid MyClass constructor then it's your responsibility to delete it. Otherwise if you delete an unallocated memory it causes undefined behavior.
An idiomatic way is to use smart pointer inside class if you need to dynamic allocate memory and delete it, smart pointer will look after memory deallocation for you.
probaby worth a read: rule of three
Or is that MyPtr destroyed when I call delete my?
No, when you call delete my; this will call the destructor of MyClass and unless you explicitly delete MyPtr in the destructor you will have a memory leak.
Should MyClass have a destructor which uses something like delete MyPtr?
Always delete dynamically allocated memory in your destructor - that is what destructors are meant for.
When you call
delete my
you don't deallocate the data of that class (unless you specify it in the destructor), so this will lead to a memory leak.
I am learning memory management in C++ and I don't get the why only some of the destructors are called when leaving scope. In the code below, only obj1 destructor is called when myfunc ends, not for the dynamically allocated obj2.
int myfunc (cl1 *oarg) {
cout << "myfunc called" << std::endl;
cl1 obj1(222,"NY");
cl1 *obj2;
obj2= new cl1;
oarg->disp();
obj2 -> ~cl1 ;
}
Here is the destructor I have :
cl1 :: ~cl1 () {
std::cout<< " cl1 destructor called"<<std::endl;
std::cout << this->data << std::endl; //just to identify the obj
delete [] str;
str = NULL ;
};
If you allocate a object using new
obj2= new cl1;
Then unless you call delete on it, its destructor won't be called implicitly.
EDIT: As #David, meantions in comments, One may call destructor of an object explicitly but in my experience there is rarely a need to manually call the destructor unless one is using placement new version of new.
Variables on stack are implicitly cleaned up(by calling their destructors) when their scope ends.
Dynamically allocated objects are not implicitly cleaned, it is the responsibility of the user to clean them up explicitly calling delete.
This is the very reason one should not use raw pointers but use smart pointers.
Dynamically allocated objects are your responsibility - you need to explicitly clean them up. Automatic objects (such as obj1) are cleaned up when the scope exits, automatically. In this case, before the scope exits - explicitly call delete obj2. NOTE: this line obj2 -> ~cl1 - does not do anything - the delete will take care of triggering the destructor correctly.
obj1 is an object of type cl1, with automatic storage duration (It is allocated on the stack, and its lifetime is determined by the scope it is in)
obj1 is an object of type cl1*. That is, it is a pointer. The pointer also has automatic storage duration, but the object it points to does not. It points to a dynamically-allocated object in the free-store.
When you leave the scope, then the objects with automatic storage duration get destroyed. obj1 gets destroyed, calling your destructor. And obj2 also gets destroyed, but obj2 isn't of type cl1, so it doesn't call cl1's destructor. It is a pointer, and it does nothing special when it is destroyed.
Pointers don't own the objects they point to, and so they do nothing to ensure the pointed-to object gets destroyed or cleaned up. (If you want an "owning" pointer, that's what smart pointer classes are for)
Consider that you can easily have multiple pointers pointing to the same object.
If a pointer automatically deleted the object it pointed to, then that would lead to errors. An object pointed to by two different pointers would get deleted twice.
obj2 -> ~cl1 ;
Don't do this! Use delete obj2; instead.
Addendum
What you were trying to do was to call the destructor explicitly. Your code does not do that. Your code is getting the address of the destructor and then dropping it into the bit bucket. Your code is a no-op. The correct way to explicitly call the destructor is obj2->~cli();.
Explicitly calling the destructor is usually something you should not do.
What you should do is to delete the memory created by new. The correct way to do that is to use the delete operator. This automatically calls the destructor and releases the memory. The destructor does not release the memory. Failing to use delete results in a memory leak.
Destructors are called automatically when an object that was created on the stack goes out of scope.
With dynamically allocated objects, you need to call delete obj. delete will automatically call your destructor for you.
You should use delete for dynamically allocated objects:
delete obj2;
this calls the destructor and frees memory. You'll be much better off using smart pointers for managing such objects - they will call delete for you even in case of exception being thrown between new and delete.
First of all you should use delete operator to destrory an object and not call its destructor directtly. Secondly, by doing new you are telling the compiler that you dont want to delete the object when it goes out of the scope. In such case you need to explictly fo delete objj2; to delete the object.
Use std::unique_ptr or std::shared_ptr instead of raw pointer.
It the best way to avoid memory leaks or double free.
That is the right way in modern C++.
int myfunc (cl1 *oarg)
{
cout << "myfunc called" << std::endl;
cl1 obj1(222,"NY");
std::unique_ptr<cl1> obj2( new cl1 );
oarg->disp();
}