Dear DaniWebbers,

If you would all be so kind to help me, I have a problem here and I am trying to know why this happens...

In a large application I am working on, I need to have a struct of some sort with a sub struct-array and the sub struct-array has its own sub struct-array. All of this is dynamically allocated. This was previously done in C and typedef structs and the like, and I am trying to make it slightly more manageable by moving it all to C++ and classes. I'll make use of constructors and destructors, and also help myself by allocating the functions to their representative classes...

The problem happens when I try to free the memory. The code below shows the exact error I am having, but in a simple example. The provided code compiles and runs, but when it gets to the third iteration of 'delete' for mySub, it crashes... it seems as if when the first subclass is deleted, it deletes all the child classes of all the others in the array. Could that be possible?

If there is a better way to implement this, please let me know.

Thanx in advance

#include <string.h>

class SubSub {
	public:
		SubSub();
		~SubSub();
		
		char   var1[30];
		char   var2[30];
		int    var3;
		double var4;
};

class Sub {
	public:
		Sub();
		~Sub();

		SubSub * mySubSub;

		char   var1[30];
		char   var2[30];
		int    var3;
		double var4;
		int    mySubSubCount;
};

class Super {
	public:
		Super();
		~Super();

		Sub * mySub;

		char   var1[30];
		char   var2[30];
		int    var3;
		double var4;
		int    mySubCount;
};

//----Constructors

Super::Super()
{
	
	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
	mySub = NULL;
	mySubCount = 0;
}

Sub::Sub()
{
	
	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
	mySubSub = NULL;
	mySubSubCount = 0;
}

SubSub::SubSub()
{
	
	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
}

//----Destructors

Super::~Super()
{
	
	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
	if (mySubCount > 0)
	{
		delete [] mySub;
	}
	mySubCount = 0;
}

Sub::~Sub()
{
	
	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
	if (mySubSubCount > 0)
	{
		delete [] mySubSub;
	}
	mySubSubCount = 0;
}

SubSub::~SubSub()
{
	
	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
}

void main()
{
	int a = 3;
	int b = 3;
	int c = 3;
	int i = 0;
	int j = 0;
	int k = 0;
	int l = 0;
	int m = 0;
	Super  * mySuper = new Super;
	Sub    * mySub;
	SubSub * mySubSub;

	do
	{

		for (i = 0; i < a; i++)
		{
			strcpy(mySuper->var1, "test1");
			strcpy(mySuper->var2, "test2");
			mySuper->var3 = 3;
			mySuper->var4 = 4;
			for (j = 0; j < b; j++)
			{
				if (mySuper->mySubCount > 0)
				{
					mySub = new Sub[mySuper->mySubCount + 1];
					for (l = 0; l < mySuper->mySubCount; l++)
					{
						mySub[l] = mySuper->mySub[l];
					}

					delete [] mySuper->mySub;
					mySuper->mySub = mySub;
					delete mySub;
					mySuper->mySubCount++;
				}
				else
				{
					mySuper->mySub = new Sub[1];
					mySuper->mySubCount = 1;
				}
				strcpy(mySuper->mySub[j].var1, "test1");
				strcpy(mySuper->mySub[j].var2, "test2");
				mySuper->mySub[j].var3 = 3;
				mySuper->mySub[j].var4 = 4;

				for (k = 0; k < c; k++)
				{
					if (mySuper->mySub[j].mySubSubCount > 0)
					{
						mySubSub = new SubSub[mySuper->mySub[j].mySubSubCount + 1];
						for (m = 0; m < mySuper->mySub[j].mySubSubCount; m++)
						{
							mySubSub[m] = mySuper->mySub[j].mySubSub[m];
						}

						delete [] mySuper->mySub[j].mySubSub;
						mySuper->mySub[j].mySubSub = mySubSub;
						delete mySubSub;
						mySuper->mySub[j].mySubSubCount++;
					}
					else
					{
						mySuper->mySub[j].mySubSub = new SubSub[1];
						mySuper->mySub[j].mySubSubCount = 1;
					}
					strcpy(mySuper->mySub[j].mySubSub[k].var1, "test1");
					strcpy(mySuper->mySub[j].mySubSub[k].var2, "test2");
					mySuper->mySub[j].mySubSub[k].var3 = 3;
					mySuper->mySub[j].mySubSub[k].var4 = 4;

				}
			}
		}
		a--;
		b--;
		c--;
	}
	while (a && b && c);
	
}

one problem:

int* x = new int; //ok
delete x; //ok

but

int* x = new int;
int* y = x;
delete x;
....
do something with y is wrong, because y is pointer to deleted object :}

ivailosp, thank you very much for the reply.

I do see that... and I understand that concept. I do not see where I would have been deleting something out of scope. When I am deleting and recreating the structure, I am refilling it all in with the same old information, except now the array is one bigger.

If I understand what's happening correctly (I hope), I am in fact filling in the second inner array (mySubSub) 3 times for every time that I am filling in the first array (mySub). The first 2 times this happens, and the first bunch of values are deleted and refilled using the new temporary array pointers, this works fine.

Tracing through the code I noticed that it breaks on the third iteration of delete [] mySubSub; .

If there is some way to make this work, please let me know.

Again, thank you all very much.

mySuper->mySub = mySub;
					delete mySub;
					mySuper->mySubCount++;
				}
				else
				{
					mySuper->mySub = new Sub[1];
					mySuper->mySubCount = 1;
				}

				strcpy(mySuper->mySub[j].var1, "test1");
				strcpy(mySuper->mySub[j].var2, "test2");
				mySuper->mySub[j].var3 = 3;
				mySuper->mySub[j].var4 = 4;

ivailosp,

Again, thank you very much for the reply.

What I thought I was doing was that I was creating a new temporary array, filling it with the same old information, and then after I delete the old (smaller) array, I am copying the values back... do I have to manually do each and every value for this to work?

Thanx;

Hey... I had tried doing that... Interesting that you'd suggest it.

I did this:

#include <vector>
#include <string.h>

class SubSub {
	public:
		SubSub();
		~SubSub();
		
		char   var1[30];
		char   var2[30];
		int    var3;
		double var4;
};

class Sub {
	public:
		Sub();
		~Sub();

		std::vector<SubSub> mySubSub;

		char   var1[30];
		char   var2[30];
		int    var3;
		double var4;
		int    mySubSubCount;
};

class Super {
	public:
		Super();
		~Super();

		std::vector<Sub> mySub;

		char   var1[30];
		char   var2[30];
		int    var3;
		double var4;
		int    mySubCount;
};

//----Constructors

Super::Super()
{
	
	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
	mySub.resize(1);
	mySubCount = 0;
}

Sub::Sub()
{

	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
	mySubSub.resize(1);
	mySubSubCount = 0;
}

SubSub::SubSub()
{
	
	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
}

//----Destructors

Super::~Super()
{
	
	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
	mySubCount = 0;
}

Sub::~Sub()
{

	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
	mySubSubCount = 0;
}

SubSub::~SubSub()
{
	
	strcpy(var1, "");
	strcpy(var2, "");
	var3 = 0;
	var4 = 0.0;
}

void main()
{
	unsigned int a = 0;
	unsigned int b = 0;
	unsigned int c = 0;
	unsigned int i = 0;
	unsigned int j = 0;
	unsigned int k = 0;
	std::vector<Super> mySuper;

	a = 30;
	b = 30;
	c = 30;

	for (i = 0; i < a; i++)
	{
		if (i >= mySuper.capacity())
		{
			mySuper.resize(mySuper.capacity() + 5);
		}
		strcpy(mySuper.at(i).var1, "test1");
		strcpy(mySuper.at(i).var2, "test2");
		mySuper.at(i).var3 = 3;
		mySuper.at(i).var4 = 4;
		for (j = 0; j < b; j++)
		{
			if (j >= mySuper.at(i).mySub.capacity())
			{
				mySuper.at(i).mySub.resize(mySuper.at(i).mySub.capacity() + 5);
			}
			strcpy(mySuper.at(i).mySub.at(j).var1, "test11");
			strcpy(mySuper.at(i).mySub.at(j).var2, "test22");
			mySuper.at(i).mySub.at(j).var3 = 33;
			mySuper.at(i).mySub.at(j).var4 = 44;

			for (k = 0; k < c; k++)
			{
				if (k >= mySuper.at(i).mySub.at(j).mySubSub.capacity())
				{
					mySuper.at(i).mySub.at(j).mySubSub.resize(mySuper.at(i).mySub.at(j).mySubSub.capacity() + 5);
				}
				strcpy(mySuper.at(i).mySub.at(j).mySubSub.at(k).var1, "test111");
				strcpy(mySuper.at(i).mySub.at(j).mySubSub.at(k).var2, "test222");
				mySuper.at(i).mySub.at(j).mySubSub.at(k).var3 = 333;
				mySuper.at(i).mySub.at(j).mySubSub.at(k).var4 = 444;
			}
		}
	}

mySuper.clear();
}

Although, once I have the iterations at 3 it works flawlessly, but when I go up above 20, they crash! I will need this to expand to 100+ in a wost-case scenario, and 200+ for safety, and it can't seem to go past 20. :(

Thanx

Up to 20 iterations, the code works...

At 21+, it errors here:

void _Xran() const
		{	// report an out_of_range error
		_THROW(out_of_range, "invalid vector<T> subscript");
		}

That code is part of the <vector> file.

Thanx

Notice that, in vectors, the capacity is not necessarily equal to the number of elements that conform the underlying vector content (this can be obtained with member vector::size), but the capacity of the actual allocated space, which is either equal or greater than the content size.

use vector::size(), not vector::capacity()

This question has already been answered. Start a new discussion instead.