How to delete a pointer in C++ properly? [duplicate] - c++

This question already has answers here:
In what cases do I use malloc and/or new?
(20 answers)
Closed 2 years ago.
I'm new to C++ and I have a question.
Lets assume you declared the variable x using the following code:
MyClass *x = new MyClass();
After using this variable, I no longer need it.
Among the following propositions, what would then be the preferred course of action and what's the difference?
Call free(x);
Call x->~MyClass();
Call MyClass::~MyClass(p);
Call delete x;
Can someone help me to understand this?
Thanks In advance.

If you create an instance via new :
MyClass *x = new MyClass();
you must delete it via delete:
delete x;
1.) Call free(x);
No. free only releases memory it does not call destructors. If you malloc memory you need to free it, but it is rare that you have to use malloc in C++ and calling free on a pointer obtained from new is wrong.
2.) Call x->~MyClass();
No. Explicitly calling the destructor is almost always wrong!
(For example when you create an object via placement new then you don't call delete but the destructor directly, because placement new creates the object in already allocated memory.)
3.) Call MyClass::~MyClass(p);
No. This makes no sense, destructors take no parameters.
4.) Call delete x;
Yes. Calling delete...
Destroys object(s) previously allocated by the new expression and releases obtained memory area
But you should not manually manage memory. Either rely on automatic storage:
MyClass x;
The detructor of x is called automatically when it goes out of scope. Or if you really need dynamic memory allocation use smart pointers.
For further reading: Why should C++ programmers minimize use of 'new'?
By the way, this is such a common misconception that each talk of Stroustrup i remember has an example that uses new to create an object and then he explains that it should definitely not use new. Actually there is more to it than forgetting to call delete. Consider:
{
MyClass *x = new MyClass();
foo();
delete x; // phew I didnt forget to call delete
}
If foo throws an exception then this code leaks memory. The right way is to rely on RAII:
{
MyClass x;
foo();
}
Now if foo throws an exception, the destructor of x will be called!

Variable dynamically allocated with the new keyword should be deleted by using the delete keyword. new and delete call the constructor and the destructor of the specified class. This means your instance is initalized and deinitialized properly.
So, instance x initialized with MyClass *x = new MyClass(); should be deleted with delete x;.
However, it is always better, if possible, to declare variable on stack like MyClass x; and let RAII do its work. Take a look at the following example:
{
// creates an object 'x' on stack
MyClass x;
// do something with 'x'
// once the object is out of scope, it is automatically being destructed
}
Furthermore, if you still need dynamic allocation, modern C++ suggests using smart pointers, like std::shared_ptr and std::unique_ptr. Smart pointers automatically take care of memory handling instead of you. In other words, by using smart pointers, you don't need to care about deleteing the object created with the new. You can write something like:
{
// creates an object 'x' on heap
// its default ctor is being called
std::shared_ptr<MyClass> x = std::make_shared<MyClass>();
// once the object is out of scope, even though it is allocated
// on the heap, there is no need to call 'delete' here because
// deletion is automatically handled by the 'std::shared_ptr'
}

Related

C++ deconstructor message not shown [duplicate]

I use extra brackets in my code. I thought when the destructor should be called after the local variable scope is ended but it doesn't work like this:
class TestClass {
public:
TestClass() {
printf( "TestClass()\n" );
}
~TestClass() {
printf( "~TestClass()\n" );
}
};
int main() {
int a, b, c;
{
TestClass *test = new TestClass();
}
}
It outputs:
TestClass()
So it doesn't call the destructor of the TestClass but why? If I call it manually (delete test) it calls the destructor, right. But why it doesn't call the destructor in the first case?
TestClass *test = new TestClass();
You using new which creates a dynamically allocated object (most likely placed on the heap). This type of resource needs to be manually managed by you. By managing, you should use delete on it after you have done using it.
{
TestClass *test = new TestClass();
// do something
delete test;
}
But for the most of your purposes and intents, you just have to use automatic-storage objects, which frees you the hassle of having to manually manage the object. It would also most likely to have better performance especially in short-lived objects. You should always prefer to use them unless you have a really good reason not to do so.
{
TestClass test;
// do something
}
However, if you need the semantics of dynamically allocated objects or that of pointers, it will always be better to use some mechanism to encapsulate the deletion/freeing of the object/resource for you, which also provides you additional safety especially when you are using exceptions and conditional branches. In your case, it would be better if you use std::unique_ptr.
{
std::unique_ptr<TestClass> test(new TestClass());
// auto test = std::make_unique<TestClass>(); in C++14
// do something (maybe you want to pass ownership of the pointer)
}
The following is a relevant link to help you decide whether to use automatic storage objects or dynamically allocated objects: Why should C++ programmers minimize use of 'new'?
Because you have a pointer to a dynamically allocated object. Only the pointer goes out of scope, not the object it points to. You have to call delete on the pointer in order for the pointee's destructor to get called.
Try with an automatic storage object instead:
{
TestClass test;
}
Here, the destructor will be called on exiting the scope.
The use of raw pointers to dynamically allocated objects in C++ is discouraged because it can easily lead to resource leaks like the one shown in your code example. If pointers to dynamically allocated objects are really needed, it is wise to handle them with a smart pointer, rather than to attempt to manually deal with their destruction.
This answer is good enough but just to add some more.
I see you have been coded with Java. In C++ to create variable/object in stack keyword new is not needed. Actually when you use keyword new your object is creating in heap and it doesn't destroys after leaving scope. To destroy it you need to call delete in your case delete test;
In such a structure as yours, after leaving scope you just lose pointer what points into object, so after leaving scope you cannot free memory and call destructor, but eventually OS call destructor just after exit() instruction is executed.
To sum up C++ != Java

Why not call Destructor in C++?

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.

Stack Overflow when deleting this Pointer

I have the following code and I get stack overflow error can anyone please explain me What's wrong here. from my understanding this pointer points to current object so why I cant delete it in a destructor;
class Object
{
private:
static int objCount;
public:
int getCount()
{
int i =10;
return i++;
}
Object()
{
cout<< "Obj Created = "<<++objCount<<endl;
cout <<endl<<this->getCount()<<endl;
}
~Object()
{
cout<<"Destructor Called\n"<<"Deleted Obj="<<objCount--<<endl;
delete this;
}
};
int Object::objCount = 0;
int _tmain(int argc, _TCHAR* argv[])
{
{
Object obj1;
}
{
Object *obj2 = new Object();
}
getchar();
return 0;
}
You're doing delete this; in your class's destructor.
Well, delete calls the class's destructor.
You're doing delete this; in your class's destructor.
...
<!<!<!Stack Overflow!>!>!>
(Sorry guys I feel obliged to include this... this might probably spoil it sorrrryyyy!
Moral of the boring story, don't do delete this; on your destructor (or don't do it at all!)
Do [1]
Object *obj = new Object();
delete obj;
or much better, just
Object obj;
[1]#kfsone's answer more accurately points out that the stack overflow was actually triggered by obj1's destructor.
'delete this' never makes sense. Either you're causing an infinite recursion, as here, or you're deleting an object while it is still in use by somebody else. Just remove it. The object is already being deleted: that's why you're in the destructor.
The crash you are having is because of the following statement:
{
Object obj1;
}
This allocates an instance of "Object" on the stack. The scope you created it in ends, so the object goes out of scope, so the destructor (Object::~Object) is invoked.
{
Object obj1;
// automatic
obj1.~Object();
}
This means that the next instruction the application will encounter is
delete this;
There are two problems right here:
delete calls the object's destructor, so your destructor indirectly calls your destructor which indirectly calls your destructor which ...
After the destructor call, delete attempts to return the object's memory to the place where new obtains it from.
By contrast
{
Object *obj2 = new Object();
}
This creates a stack variable, obj2 which is a pointer. It allocates memory on the heap to store an instance of Object, calls it's default constructor, and stores the address of the new instance in obj2.
Then obj2 goes out of scope and nothing happens. The Object is not released, nor is it's destructor called: C++ does not have automatic garbage collection and does not do anything special when a pointer goes out of scope - it certainly doesn't release the memory.
This is a memory leak.
Rule of thumb: delete calls should be matched with new calls, delete [] with new []. In particular, try to keep new and delete in matching zones of authority. The following is an example of mismatched ownership/authority/responsibility:
auto* x = xFactory();
delete x;
Likewise
auto* y = new Object;
y->makeItStop();
Instead you should prefer
// If you require a function call to allocate it, match a function to release it.
auto* x = xFactory();
xTerminate(x); // ok, I just chose the name for humor value, Dr Who fan.
// If you have to allocate it yourself, you should be responsible for releasing it.
auto* y = new Object;
delete y;
C++ has container classes that will manage object lifetime of pointers for you, see std::shared_ptr, std::unique_ptr.
There are two issues here:
You are using delete, which is generally a code smell
You are using delete this, which has several issues
Guideline: You should not use new and delete.
Rationale:
using delete explicitly instead of relying on smart pointers (and automatic cleanup in general) is brittle, not only is the ownership of a raw pointer unclear (are you sure you should be deleting it ?) but it is also unclear whether you actually call delete on every single codepath that needs it, especially in the presence of exceptions => do your sanity (and that of your fellows) a favor, don't use it.
using new is also error-prone. First of all, are you sure you need to allocate memory on the heap ? C++ allows to allocate on the stack and the C++ Standard Library has containers (vector, map, ...) so the actual instances where dynamic allocation is necessary are few and far between. Furthermore, as mentioned, if you ever reach for dynamic allocation you should be using smart pointers; in order to avoid subtle order of execution issues it is recommend you use factory functions: make_shared and make_unique (1) to build said smart pointers.
(1) make_unique is not available in C++11, only in C++14, it can trivially be implemented though (using new, of course :p)
Guideline: You shall not use delete this.
Rationale:
Using delete this means, quite literally, sawing off the branch you are sitting on.
The argument to delete should always be a dynamically allocated pointer; therefore should you inadvertently allocate an instance of the object on the stack you are most likely to crash the program.
The execution of the method continues past this statement, for example destructors of local objects will be executed. This is like walking on the ghost of the object, don't look down!
Should a method containing this statement throw an exception or report an error, it is difficult to appraise whether the object was successfully destroyed or not; and trying again is not an option.
I have seen several example of usage, but none that could not have used a traditional alternative instead.

C++: why it doesn't call a destructor?

I use extra brackets in my code. I thought when the destructor should be called after the local variable scope is ended but it doesn't work like this:
class TestClass {
public:
TestClass() {
printf( "TestClass()\n" );
}
~TestClass() {
printf( "~TestClass()\n" );
}
};
int main() {
int a, b, c;
{
TestClass *test = new TestClass();
}
}
It outputs:
TestClass()
So it doesn't call the destructor of the TestClass but why? If I call it manually (delete test) it calls the destructor, right. But why it doesn't call the destructor in the first case?
TestClass *test = new TestClass();
You using new which creates a dynamically allocated object (most likely placed on the heap). This type of resource needs to be manually managed by you. By managing, you should use delete on it after you have done using it.
{
TestClass *test = new TestClass();
// do something
delete test;
}
But for the most of your purposes and intents, you just have to use automatic-storage objects, which frees you the hassle of having to manually manage the object. It would also most likely to have better performance especially in short-lived objects. You should always prefer to use them unless you have a really good reason not to do so.
{
TestClass test;
// do something
}
However, if you need the semantics of dynamically allocated objects or that of pointers, it will always be better to use some mechanism to encapsulate the deletion/freeing of the object/resource for you, which also provides you additional safety especially when you are using exceptions and conditional branches. In your case, it would be better if you use std::unique_ptr.
{
std::unique_ptr<TestClass> test(new TestClass());
// auto test = std::make_unique<TestClass>(); in C++14
// do something (maybe you want to pass ownership of the pointer)
}
The following is a relevant link to help you decide whether to use automatic storage objects or dynamically allocated objects: Why should C++ programmers minimize use of 'new'?
Because you have a pointer to a dynamically allocated object. Only the pointer goes out of scope, not the object it points to. You have to call delete on the pointer in order for the pointee's destructor to get called.
Try with an automatic storage object instead:
{
TestClass test;
}
Here, the destructor will be called on exiting the scope.
The use of raw pointers to dynamically allocated objects in C++ is discouraged because it can easily lead to resource leaks like the one shown in your code example. If pointers to dynamically allocated objects are really needed, it is wise to handle them with a smart pointer, rather than to attempt to manually deal with their destruction.
This answer is good enough but just to add some more.
I see you have been coded with Java. In C++ to create variable/object in stack keyword new is not needed. Actually when you use keyword new your object is creating in heap and it doesn't destroys after leaving scope. To destroy it you need to call delete in your case delete test;
In such a structure as yours, after leaving scope you just lose pointer what points into object, so after leaving scope you cannot free memory and call destructor, but eventually OS call destructor just after exit() instruction is executed.
To sum up C++ != Java

What are the dynamics of the C++ delete statement?

This is merely for curiosity sake because I have not used new and delete in c++ except for the most basic uses.
I know that delete releases memory. The thing I'm wondering is how does it handle more complex cases?
For instance, if I have a user-defined class like this:
class MyClass
{
public:
MyClass();
~MyClass()
{
delete [] intArray;
}
//public members here
private:
int* intArray;
};
Assuming the class allocates memory somehow for intArray, and then release it in the destructor, What if I used the class like this: MyClass* myClass = new MyClass(); and released it later with delete myclass;
How does delete handle the releasing of all the memory? Does the class destructor get called first to release all of the memory allocated by the class (ie int* intArray) and then release the memory allocated to hold the class?
What if I had a class like this:
class MyClass
{
public:
MyClass();
~MyClass()
{
delete anotherMyClass;
}
//public members here
private:
MyClass* anotherMyClass;
};
Assuming anotherMyClass is not allocated with the constructor, which would use up memory very quickly, what if there was a chain of MyClasses attached to each other like a linked-list? Would the delete statement in the destructor work in this case? Would each anotherMyClass be recursively released when the destructor gets called?
Are there any specific weird tricks or caveats with the new and delete statements that you know about?
Given a pointer (p) to a dynamically allocated object, delete does two things:
It calls the destructor of the dynamically allocated object. Note that when ~MyClass() completes, the destructors for any member variables of class type are called.
It frees the memory occupied by the dynamically allocated object.
It doesn't search the member variables of the object for other pointers to free; it doesn't free any other memory and doesn't do anything else.
If you need to free the memory pointed to by intArray, you need to delete it in the destructor of MyClass.
However, in almost all C++ code, you don't need to worry about this. You should be using smart pointers like shared_ptr, unique_ptr, auto_ptr, and scoped_ptr to automatically manage dynamically allocated objects. Manual resource management is difficult at best and should be avoided wherever possible.
This is part of a broader idiom, Scope-Bound Resource Management (SBRM, also called Resource Acquisition is Initialization, or RAII). This is by far the most important design pattern to understand and to use everywhere in your C++ code.
If in your class you had declared this instead:
boost::scoped_ptr<int> intArray;
then when the scoped_ptr<int> object is destroyed, it will free the pointer that it holds. You then do not have to do any work to manually destroy the object.
In well-written, modern C++ code, you should rarely need to manually use delete. Smart pointers and other SBRM containers should be used to manage any type of resource that needs cleanup, including dynamically allocated objects.
In your second example, given a linked list that looks like:
x -> y -> z -> 0
you would have an order of operations that looks like this:
delete x;
x.~MyClass();
delete y;
y.~MyClass();
delete z;
z.~MyClass();
delete 0;
[free memory occupied by z]
[free memory occupied by y]
[free memory occupied by x]
The objects in the linked list would be destroyed in reverse order.
delete intArray;
I assume intArray points to the first element of an int array? In that case, delete intArray yields undefined behavior. If you allocate via new[], you must release via delete[].
delete[] intArray;
Yes I know, delete intArray might appear to work just fine on certain systems with certain compiler versions under certain compiler options -- or it might not. That's undefined behavior for ya.
Also, you should follow the Rule of Three. Defining your own destructor but relying on the implicitly-defined copy constructor and copy assignment operator is a recipe for disaster.