Re: Destructor that implies another destructor call (using new/delete)
- From: "Giovanni Dicanio" <giovanniDOTdicanio@xxxxxxxxxxxxxxxxx>
- Date: Thu, 5 Mar 2009 15:57:29 +0100
[...]Trying to solve a memory allocation/deallocation issue in VC6. Have an
object A which, when initialized, allocates within itself objects of
type X, and X also internally allocates a few simple arrays
dynamically.
[...] the destructors as built are not
handling the 'nested' allocations, it appears. Anyone have ideas, or
good reference material? Much thanks
I mean: in a C++ program I would use modern C++ container classes (like
std::vector, instead of new[]) and smart pointers, as Doug already
suggested.
Just as an addition of previous sample code, I thought it might be useful for you OP to post a version of that code that uses modern C++ classes like std::vector and shared_ptr.
Note that thanks to both these classes the code complexity is reduced.
For example: there is no need to explicitly delete the arrays allocated with new[] using delete[], thanks to std::vector destructor. The deletion is implicit: the destructor of the class that has std::vector data members will automatically call the std::vector destructor, so each std::vector instance will be automatically cleaned up.
Moreover, thanks to "vector of shared_ptr", there is no need to loop through the vector items, deleting every single pointed object, and then deleting the whole vector; the synergy of both vector and shared_ptr allows you to just do nothing. The power and elegance of STL classes will do proper cleanup of both the pointed objects and the vector storing the (smart) pointers automatically.
For more information about shared_ptr, you may want to consider this post on VC++ Team Blog:
http://blogs.msdn.com/vcblog/archive/2008/02/22/tr1-slide-decks.aspx
Note that if you use VS2008 with SP1, you will have shared_ptr ready "out of the box".
Instead, if you use a previous version like VC6, you should use Boost implementation.
Giovanni // Test.cpp - Modern C++ version
#include <iostream>
#include <vector> // STL vector
#include <assert.h>
#include <boost\shared_ptr.hpp> // or use TR1 implementation that comes with VS2008 SP1
using std::cout;
using std::endl;
using std::vector;
class X
{
public:
explicit X(int n)
{
cout << "[X Constructor] Creating two vectors of size " << n << endl;
// Create arrays
assert(n > 0);
m_array1.resize(n);
m_array2.resize(n);
}
~X()
{
cout << "[X Destructor] Deleting stored arrays of size " << m_array1.size() << endl;
// std::vector data members destructors automatically called here
}
// Get array size
int GetSize() const
{
return m_array1.size();
}
// Get array #1 pointer
int * GetArray1()
{
return &m_array1[0];
}
// Get array #2 pointer
int * GetArray2()
{
return &m_array2[0];
}
//
// Data Members
//
private:
// Arrays stored by X
vector<int> m_array1;
vector<int> m_array2;
};
// "Smart" pointer to X
typedef boost::shared_ptr< X > SmartPtrX;
class A
{
public:
explicit A(int n)
{
cout << "[A Constructor] Creating " << n << " instances of X embedded." << endl;
// Create the objects
const int xInitParameter = 2;
for (int i = 0; i < n; i++)
{
// Add smart pointers to instances of X inside the vector
m_objX.push_back( SmartPtrX( new X(xInitParameter) ) );
}
}
~A()
{
cout << "[A Destructor] Deleting instances of X embedded." << endl;
// STL vector and shared_ptr "automagically" do proper cleanup
}
int GetCount() const
{
return m_objX.size();
}
SmartPtrX GetStoredObjectAt(int index)
{
return m_objX[index];
}
private:
// Stores pointers to objects of type X, using smart pointer (shared_ptr)
vector< SmartPtrX > m_objX;
};
void Test()
{
A a(2);
}
int main()
{
Test();
return 0;
}
- Follow-Ups:
- References:
- Destructor that implies another destructor call (using new/delete)
- From: chrisisid
- Re: Destructor that implies another destructor call (using new/delete)
- From: Giovanni Dicanio
- Destructor that implies another destructor call (using new/delete)
- Prev by Date: Re: Thread pool design logic suggestions
- Next by Date: Re: String constant's "constness"
- Previous by thread: Re: Destructor that implies another destructor call (using new/delete)
- Next by thread: Re: Destructor that implies another destructor call (using new/delete)
- Index(es):
Relevant Pages
|