I have an class A
which uses a heap memory allocation for one of its fields. Class A is instantiated and stored as a pointer field in another class (clas
You have something like
class B
{
A * a;
}
B * b = new B;
b->a = new A;
If you then call delete b;
, nothing happens to a, and you have a memory leak. Trying to remember to delete b->a;
is not a good solution, but there are a couple of others.
B::~B() {delete a;}
This is a destructor for B that will delete a. (If a is 0, that delete does nothing. If a is not 0 but doesn't point to memory from new, you get heap corruption.)
auto_ptr<A> a;
...
b->a.reset(new A);
This way you don't have a as a pointer, but rather an auto_ptr<> (shared_ptr<> will do as well, or other smart pointers), and it is automatically deleted when b is.
Either of these ways works well, and I've used both.
I was wondering why my class' destructor was not called. The reason was that I had forgot to include definition of that class (#include "class.h"). I only had a declaration like "class A;" and the compiler was happy with it and let me call "delete".
When you call delete on a pointer allocated by new, the destructor of the object pointed to will be called.
A * p = new A;
delete p; // A:~A() called for you on obkect pointed to by p
The destructor for the object of class A will only be called if delete is called for that object. Make sure to delete that pointer in the destructor of class B.
For a little more information on what happens when delete is called on an object, see: http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.9
The destructor of A will run when its lifetime is over. If you want its memory to be freed and the destructor run, you have to delete it if it was allocated on the heap. If it was allocated on the stack this happens automatically (i.e. when it goes out of scope; see RAII). If it is a member of a class (not a pointer, but a full member), then this will happen when the containing object is destroyed.
class A
{
char *someHeapMemory;
public:
A() : someHeapMemory(new char[1000]) {}
~A() { delete[] someHeapMemory; }
};
class B
{
A* APtr;
public:
B() : APtr(new A()) {}
~B() { delete APtr; }
};
class C
{
A Amember;
public:
C() : Amember() {}
~C() {} // A is freed / destructed automatically.
};
int main()
{
B* BPtr = new B();
delete BPtr; // Calls ~B() which calls ~A()
C *CPtr = new C();
delete CPtr;
B b;
C c;
} // b and c are freed/destructed automatically
In the above example, every delete and delete[] is needed. And no delete is needed (or indeed able to be used) where I did not use it.
auto_ptr
, unique_ptr
and shared_ptr
etc... are great for making this lifetime management much easier:
class A
{
shared_array<char> someHeapMemory;
public:
A() : someHeapMemory(new char[1000]) {}
~A() { } // someHeapMemory is delete[]d automatically
};
class B
{
shared_ptr<A> APtr;
public:
B() : APtr(new A()) {}
~B() { } // APtr is deleted automatically
};
int main()
{
shared_ptr<B> BPtr = new B();
} // BPtr is deleted automatically