PDA

View Full Version : Problems deallocating memory - C++


sage45
10-14-2005, 10:44 PM
I'm having a problem when trying to delete the allocated memory for a class using inheritance...

When declared as:
// in main
Base **BasePtr; // Pointer to a pointer to a class called Base. Base is a pure virtual class.

// after reading in ArraySize
BasePtr = new Base*[ArraySize]; // Make a new array of pointers
for (i = 0; i < ArraySize; i++)
BasePtr[i] = NULL;

char switch_var;
inFile >> switch_var;
switch(switch_var)
{
case 'S': BasePtr[index] = new Child1; // create new instance of Child1 class.
BasePtr[index] -> input(inFile); // call virtual input function, inheritance will call the Child1 implementation.
break;
case 'T': BasePtr[index] = new Child2; // create new instance of Child2 class.
BasePtr[index] -> input(inFile); // call virtual input function, inheritance will call the Child2 implementation.
break;
case 'P': BasePtr[index] = new Child3; // create new instance of Child3 class.
BasePtr[index] -> input(inFile); // call virtual input function, inheritance will call the Child3 implementation.
break;
default: cerr << "Bad data in input file." << endl;
exit(1);
}I would assume then that I could simply deallocate the memory as such:for (i = 0; i < ArraySize; i++)
delete[] *BasePtr;

delete[] BasePtr;This however does not work, I get an assertion error everytime. So then I tried this way:for (int k = 0; k < ArraySize; k++)
delete[] BasePtr[k]; // delete each individual charge

delete[] BasePtr; // delete array of pointers to chargeAnd again I get an assertion error. From what I understand, an assertion error happens when you try to deallocate memory that you do not own, however, I know that I own this memory because I can do the following:for (int i = 0; i < ArraySize; i++)
{
cout << someVirtualChildFunction();
}And I get the correct output from that memory location... How can I deallocate this memory???

Thanks,

-sage-

felgall
10-14-2005, 11:40 PM
Try

delete BasePtr[]; // delete BasePtr array.

sage45
10-15-2005, 12:24 AM
Thanks... It works...

-sage-

aman
10-15-2005, 12:46 AM
You need to delete each individual pointer first, then the base array

You were real close with one of your tries..

for (int k = 0; k < ArraySize; k++)
delete BasePtr[k]; // delete each individual charge

delete[] BasePtr; // delete array of pointers to charge

sage45
10-15-2005, 06:59 AM
Thanks Aman... I actually ended using that method...

Now correct me if I'm wrong, but the reason that the second method was needed was because I did not declare new BasePtr's for my second pointer?

In other words, since each instance of the BasePtr was a different Child class or datatype, then I had to delete each instance seprately and could not dereference the pointer itself?

A little explanation would be greatly appreciated...

Thanks for you help,

-sage-

aman
10-15-2005, 11:46 AM
I'm not sure I understand your question, what do you mean by "the second method was needed"?

Basically everywhere you use a new, you need a corresponding delete.

If you allocate memory for a pointer, delete the memory directly
char* p = new char;
delete p;

If you allocate memory for an array, delete the array
char* p = new char[256];
delete[] p;

pointer[n] = new char[256];
delete[] pointer[n];

Note: most compilers will allow you to call
delete pointer[n];
because deleting a block of storage works the same if it's an array or a chunk of bytes, but the proper way to call it is
delete[] pointer[n];


int main()
{
int i;

char** p = new char*[10];

for( i = 0; i < 10; i++ )
{
p[i] = new char[5];
}



for( i = 0; i < 10; i++ )
{
delete[] p[i];
}

delete[] p;


return 0;
}

sage45
10-17-2005, 12:35 AM
Well the basis of the question was that I have used somthing like the following with success:int **ptr;
ptr = new int*[20];

for(int idx = 0; idx < 20; idx++)
{
ptr[idx] = new int[20];
}

// Do some things

for(int idx = 0; idx < 20; idx++)
{
delete[] *ptr;
ptr[idx] = NULL;
}

delete[] ptr;

Now the question arises that when I attempted that this time, I was unable to do so. I was wondering if the Base class being a pure virtual class had anything to do with it?

Thanks for your response,

-sage-

aman
10-17-2005, 08:58 AM
First fix the mistake in your code, then see what's happening.

The line:
delete[] *ptr;

is wrong.. you are deleting the same ptr 20 times. Some compilers will allow this without crashing, but others wont. You need to increment the pointer location somehow.

This will work:
delete[] ptr[idx];

Or this:
delete[] *(ptr + idx);

Or this:
char **p = ptr;
for(...)
delete[] *p++;

sage45
10-17-2005, 07:59 PM
Cool thanks...