Deleting a structure

G

Guest

Hi again,

I've defined the following structure:

typedef struct _MYSTRUCT{
CTypedPtrArray<CPtrArray,SECSTRUCT*> a;
CTypedPtrArray<CPtrArray,SECSTRUCT*> b;
BYTE d;
BOOL c;
USHORT e;
}MYSTRUCT,*PMYSTRUCT;

Additionally, there's a CTypedPtrArray<CPtrArray,MYSTRUCT*> mydata;.
Now, all these arrays are filled like this:

MYSTRUCT *m = new MYSTRUCT;
//[...] fill in data. Data for a and b is also created by 'new' and added to
the list
mydata.Add(m);

The incident happens when I try to free all the allocated memory again. So,
I walk the array in mydata:
MYSTRUCT *a = NULL;
for(int i = 0; i < mydata.GetCount();i++)
{
a = (MYSTRUCT*)mydata.GetAt(i);
for(int x = 0; x < a->a.GetCount();x++)delete (SECSTRUCT*)a->a.GetAt(x);
//same for a->b goes here

//Now, this is critical:
delete a;
}

When I execute the last 'delete'- statement the program goes on rampage
(errors in different places - they don't occur when I don't delete a.
(Perhaps the whole has got something to do with these MFC classes
CTypedPtrArray and that therefore sizeof(MYSTRUCT) is not const - or I may be
completely wrong).

Any ideas why this happens?

Thanks
Peter
 
L

Larry Brasfield

Peter Schmitz said:
Hi again,
Hi.

[snip]
There is nothing wrong with the code I snipped, at least not
that explains your problem. I can guarantee that you have
not uncovered some long-latent bug in MFC container code.
The incident happens when I try to free all the allocated memory again. So, ....
//Now, this is critical:
delete a; ....
When I execute the last 'delete'- statement the program goes on rampage
(errors in different places - they don't occur when I don't delete a.
(Perhaps the whole has got something to do with these MFC classes
CTypedPtrArray and that therefore sizeof(MYSTRUCT) is not const

Your supposition is not correct and is a dead end; 'sizeof'
is a compile time construct. It never changes at runtime.
- or I may be completely wrong).

Any ideas why this happens?

In general, when delete (or free()) causes misbehavior it is because
of one of two errors: (1) The object (or memory) has already been
deleted (or free()'ed); or (2) Some portion of the heap used for
book-keeping by the heap manager has been corrupted, typically
by writing past the end of an array, but maybe by a completely
random write thru a bogus pointer.

There is nothing in what you posted to suggest which of these
sins you have committed. I leave it to you to either show more
code, (in the form of a minimal program that exhibits the bug),
or go discover the nature of your sin on your own.
 
S

Simon Trew

Peter Schmitz said:
Hi again,

I've defined the following structure:

typedef struct _MYSTRUCT{
CTypedPtrArray<CPtrArray,SECSTRUCT*> a;
CTypedPtrArray<CPtrArray,SECSTRUCT*> b;
BYTE d;
BOOL c;
USHORT e;
}MYSTRUCT,*PMYSTRUCT;

Additionally, there's a CTypedPtrArray<CPtrArray,MYSTRUCT*> mydata;.
Now, all these arrays are filled like this:

MYSTRUCT *m = new MYSTRUCT;
//[...] fill in data. Data for a and b is also created by 'new' and added to
the list
mydata.Add(m);

The incident happens when I try to free all the allocated memory again. So,
I walk the array in mydata:
MYSTRUCT *a = NULL;
for(int i = 0; i < mydata.GetCount();i++)
{
a = (MYSTRUCT*)mydata.GetAt(i);
for(int x = 0; x < a->a.GetCount();x++)delete (SECSTRUCT*)a->a.GetAt(x);
//same for a->b goes here

//Now, this is critical:
delete a;
}

When I execute the last 'delete'- statement the program goes on rampage
(errors in different places - they don't occur when I don't delete a.

At first site, this all looks reasonable. CPtrArray does not delete the
pointees so it's not a case of double deletion.
The C-style cast to SECSTRUCT* in the delete line is suspicious--
CTypedPtrArray::GetAt should return you a SECSTRUCT*, so there should be no
need to cast. If you find you do need to cast, something is not as it seems.
 
B

benben

Hi again,

I've defined the following structure:

typedef struct _MYSTRUCT{
CTypedPtrArray<CPtrArray,SECSTRUCT*> a;
CTypedPtrArray<CPtrArray,SECSTRUCT*> b;
BYTE d;
BOOL c;
USHORT e;
}MYSTRUCT,*PMYSTRUCT;

Additionally, there's a CTypedPtrArray<CPtrArray,MYSTRUCT*> mydata;.
Now, all these arrays are filled like this:

MYSTRUCT *m = new MYSTRUCT;
//[...] fill in data. Data for a and b is also created by 'new' and added to
the list
mydata.Add(m);

Wait a minute, are you adding mydata to m or m to mydata?
 
B

benben

You must call CPtrArray::RemoveAll() after all individual elements are
deleted, but it doesn't seem to be the source of the problem

ben
 
I

Ian Semmel

Using for statements and GetCount() while deleteing list items is veryconfusing. I think thee might be some boundary problem on the lastiteration.

A better wway to do it is :

while ( ! mydata.IsEmpty () )
{
MYSTRUCT* a = mydata.RemoveHead ();
while ( ! a -> a.IsEmpty () )
delete a -> a.RemoveHead ();
while ( ! a -> b.IsEmpty () )
delete a -> b.RemoveHead ();
delete a;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top