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.
Related
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.
i new on c++ object oriented program. i look in c++, when i want to create new object i can make as a pointer
MyClass* myobject1 = new MyaClass();
and i must to delete explicit when i want to garbage the object from memory, like delete object.
My question, Assume inside myobject1 i created a new object pointer (ex. MyClass2 myobject2 = new MyCalss2()). When i delete myobject1, should i do explicity delete too myobject2 on deconstructor myobject1, or myobject2 automatic will garbage?
If you have allocated Dynamic memory,Open database connection or open a file,In C++ ,It is your duty to free the allocated memory,close database connections & close files.
If you use smart pointers for Dynamic memory allocation, you don't need to worry about freeing allocated memory .Smart pointers will free the allocated memory when they goes out of the scope.
In your Question,In MyClass object you have dynamically allocated memory for MyClass2 object.You have to write your own destructor for MyClass2 & it must be called MyClass destructor. If you haven't write proper destructor for MyClass2, when you call delete on myobject1, It will call MyClass destructor & inside default destructor of MyClass2 will be called & it will not free dynamically allocated memory.
https://www.linkedin.com/pulse/write-bu-gamindu-udayanga/?lipi=urn%3Ali%3Apage%3Ad_flagship3_profile_view_base_post_details%3BtIg1TW%2BKT7ugkY8Vs3s6Ng%3D%3D
You answered your question.
"i must to delete explicit when i want to garbage the object from memory, like delete object."
There is no garbage collection in C++. If you create a new pointer you have to delete it to avoid memory leaks. You can also use helper classes such as auto_ptr, unique_ptr, shared_ptr etc according to the usage.
Let's assume I have two classes named classA and classB. I create a pointer to classA, and then dynamically allocate a single object using the new operator as follows:
classA *ptrA = new classA
classA has a member of type pointer to classB, and in its default constructor it allocates an array of objects of type classB on the heap as follows:
memberOfA = new classB[10]
and to complicate things further, classB has a member variable of type int*, and in its default constructor it allcoates an array of integer on the heap as follows:
memberOfB = new int[100]
Now, if I call a delete on ptrA using delete ptrA, how will the compiler go about deallocating the memory allocated by memberOfA and memberOfB.
Now, if I call a delete on ptrA using delete ptrA, how will the compiler go about deallocating the memory allocated by memberOfA and memberOfB.
When you call delete ptrA, the compiler will call the destructor of classA. If that destructor doesn't delete [] memberOfA then you're leaking both memberOfA and consequently memberOfB.
If instead of manual memory management (new and delete) you used automatic memory management (SBRM/RAII), then you wouldn't have to write any destructors and the resources you allocated would be freed as expected, for example:
std::unique_ptr<classA> ptrA(new classA);
std::unique_ptr<classB[]> memberOfA(new classB[10]);
std::unique_ptr<int[]> memberOfB(new int[100]);
This is in fact the modern C++ way to do it. The code becomes simpler to understand as the ownership semantics of the pointers are written in their type and there are no destructors lying around. An even better way would be to use std::make_unique(...) in place of new but I left it out for simplicity.
memberOfA and memberOfB is only deallocated if you put a delete[] in the destrutors of classA and classB. So if you had written the destructor of classA so that it freed the memory pointed to by memberOfA like this:
classA::~classA() {
delete [] memberOfA;
}
In this case the destructor would free the array calling the destructors of the elements pointed by the entries in memberOfA. The same can be said for the destructor of classB:
classB::~classB() {
delete [] memberOfB;
}
Remember using new must be paired with a subsequent delete at some point, if not you are look at a leak. Perhaps you should consider one of the smart pointer classes: unique_ptr, and shared_ptr.
If your design allows for classA and classB to use a unique_ptr or shared_ptr to the array, much of the dangers of a leak would have been overcome:
std::unique_ptr<classB[]> memberOfA(new classB[10]);
If the order of the deletion is of interest to you then, invoking the delete ptrA will result in the destructor of classA being called, and if we assume that it is implemented as hinted above (using delete []) then the delete [] operator will call the destructors of all the members in decreasing address order, quote from the Standard, draft N3690, ยง 5.3.5 / 6:
If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted. In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion of their constructor; see 12.6.2).
This will of course lead to the destructor of classB being called for each element, which will again utilize the delete [] memberOfB which will release the array pointing to the integers.
It will not ... you should do that by implementing the destructor! You can do that by using the delete [] operator.
classA::~classA() {
delete [] memberOfA;
}
and
classB::~classB() {
delete [] memberOfB;
}
and then you do delete ptrA the order of execution will be:
call classA::~classA()
call classB::~classB() on each of the elements of memberOfA
deallocate memory for the array of ints pointed by memberofB
deallocate memory for the array of memberofA
deallocate memory for classA
Deallocation of memory can actually happen at later stages in some cases.
Alternatively, if you don't really need to work with pointer use arrays or vectors to hold your elements.
class classB
{
...
std::array<int,100> memberOfB;
...
};
class classA
{
...
std::array<classB,10> memberOfA;
...
};
std::unique_ptr<A> ptrA(new classA)
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.
As referenced in this site...
http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10
But i did not find the reason, why we should explicitly call the desturctor?
You can think of it as a call to delete, but since you used placement new, you don't want to use delete, as that would attempt to free the memory. If you wanted it to be called automatically, you could use RAII:
// Could use a templated version, or find an existing impl somewhere:
void destroy_fred(Fred* f) {
f->~Fred();
}
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
boost::shared_ptr<Fred> f(new(p) Fred(), destroy_fred);
// ...
// No need for an explicit destructor, cleaned up even during an exception
}
Normally, newed objects are destructed when delete is called. delete is never called for placement new, so you have to figure out when to destruct the object yourself, and do so explicitly.
You can't call ordinary delete because that would attempt free the memory, which was not allocated with ordinary new, so you call the destructor directly and then handle the underlying memory allocation depending on the architecture you are using.
Normally, an object is created using new, and destroyed when you call delete on the object. However, because 'delete' will also try to free the underlying memory back to the heap, you should never call delete on an object which which was instantiated using placement new.
Nevertheless, (no matter how it was allocated) every object ought to be destroyed (because its destructor might do something important).
Therefore instead of the object's being destroyed using delete, you have to destroy the object yourself, and do so explicitly, by invoking its destructor as shown in the FAQ you cited.
The example from your link:
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
...
f->~Fred(); // Explicitly call the destructor for the placed object
}
"placement new" return the memory offset that we provide. Right after new the compiler adds a call to the ctor ("placement new" is a also a trick to explicity call a ctor).
"memory" is allocated in the stack so we can not delete it.
string *ps = new string("Hello ");
The new in the above statement is called new operator which do two things
Call operator new(allocates
necessary memory like malloc) and
Call constructor
on raw memory created by operator
new to initialize
delete ps;
Again delete corresponds to
Destruction of object and
Deallocation of memory(i.e, free)
In c++ user is not allowed to call constructor directly,Placement new is used when you have raw memory allocated by some means and wanted to initialize the bits with constructor.Because the memory allocation process did not happen through operator new, delete cannot deallocate the memory.
void someCode()
{
char memory[sizeof(Fred)];//memory allocated on stack
void* p = memory;
Fred* f = new(p) Fred();//placement new
...
f->~Fred(); // Explicitly call the destructor for the placed object
}