Re: Destructor that implies another destructor call (using new/delete)

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance




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;
}


Relevant Pages

  • Re: Pointers to Arrays
    ... Nice try to work with pointers ... void segregateXY ... I would like to split it into two 1D arrays, ...
    (comp.lang.c)
  • Re: malloc and pointer hell
    ... >array (pointers to pointers). ... This allocates space for only one pointer. ... place is an int**. ... you no longer have access to the memory that was ...
    (comp.lang.c)
  • Re: Doubt about arrays name
    ... basicly pointers are arrays and arrays are pointers, ... but "int main" is better. ... In this case, for traversing a string, using int can't ...
    (comp.lang.c)
  • Re: Why is the pointer passed into the function still NULL?
    ... Specifically about pointers to pointers and 2D arrays. ... get_table can't change maintable no matter how many *s the declaration ... Step back a bit and think about a function that takes an int: ...
    (comp.lang.c)
  • Re: why do the following crash
    ... extern int *arr; ... Try extern int arrin File2.c. ... Arrays and pointers aren't supposed to be interchangable. ...
    (comp.lang.c)