Assertion in dbgheap.c
Svetlana Guljajeva -- svetlana@assert.ee
Thursday, October 24, 1996
Environment: Win95,VC4.2
Hi!
Executing an application I got an exception in dbgheap.c in the following place:
/* Error if freeing incorrect memory type */
_ASSERTE(pHead->nBlockUse == nBlockUse);
(line 1051 in my version).
It happens while I am freeing memory that was used by one list (CPtrList
derivative).
The code looks like this:
void CRowHeaderList::RemoveAll()
{
POSITION pos1,pos2;
CRowHeader * pCur;
for( pos1 = GetHeadPosition(); ( pos2 = pos1 ) != NULL; )
{
if( (CRowHeader*)GetNext( pos1 ) )
{
pCur = (CRowHeader *)GetAt( pos2 );
RemoveAt( pos2 );
delete pCur; //<<<--- HERE COMES THE ASSERTION
}
}
}
pCur is of Type CRowHeader class.It has an empty constructor.
Stack at the moment of assertion looks like this:
_free_dbg(void * 0x01256470, int 1) line 970 + 13 bytes
operator delete(void * 0x01256470) line 282 + 12 bytes
??3CObject@@SGXPAX@Z + 9 bytes
CRowHeader::`scalar deleting destructor'() + 39 bytes
CRowHeaderList::RemoveAll() line 93 + 35 bytes
I have no any idea of where error could be.Have you?
Thanks in advance,
Svetlana Guljajeva
-----------------------------------------
**svetlana@assert.ee**
//**Assert Ltd.**\\
//****Tallinn****\\
//****Estonia****\\
John Young -- jyoung@gol.com
Monday, October 28, 1996
[Mini-digest: 4 responses]
At 11:46 am 24/10/96 +0200, you wrote:
>Environment: Win95,VC4.2
>Executing an application I got an exception in dbgheap.c in the following
place:
> ...
>It happens while I am freeing memory that was used by one list (CPtrList
>derivative).
>The code looks like this:
>
>void CRowHeaderList::RemoveAll()
>{
> POSITION pos1,pos2;
> CRowHeader * pCur;
>
> for( pos1 = GetHeadPosition(); ( pos2 = pos1 ) != NULL; )
> {
> if( (CRowHeader*)GetNext( pos1 ) )
> {
> pCur = (CRowHeader *)GetAt( pos2 );
> RemoveAt( pos2 );
> delete pCur; //<<<--- HERE COMES THE ASSERTION
> }
> }
The first time through the loop pos2 is uninitialised. I always use this...
while ( !IsEmpty() )
{
CYourObj* pObj = (CYourObj*) RemoveHead();
delete pObj;
}
HTH
-John
John Young, Yaesu Musen Co., Ltd., Japan.
If only computers did what you wanted, not what you tell them.
-----From: Dong Chen
If the only purpose of this function is to empty the list, I would try:
(make sure you call IsEmpty() before calling this function)
void CRowHeaderList::RemoveAll()
{
POSITION pos1,pos2;
CRowHeader * pCur;
pos1 = GetHeadPosition();
while(pos1!=NULL)
{
pos2 = pos1; // pos2 is at current position
pCur = (CRowHeader*)GetNext( pos1 ); // pos1 moves
to next
delete pCur;
// pCur is still the current one
RemoveAt(pos2);
}
}
-----From: Lior Messinger <100274.2607@CompuServe.COM>
Does the scenario invoves a DLL in soem way?
It might happen if you are using it in a DLL, or calling it from another DLL, and you link MFC
staticaly.
Regards,
Lior.
-----From: Mike Blaszczak
At 11:46 10/24/96 +0200, Svetlana Guljajeva wrote:
>Environment: Win95,VC4.2
Are you using MFC 4.2 or MFC 4.2b? You should upgrade to MFC 4.2b, and you
should report the versions MFC and VC++ you're using seperately.
>Executing an application I got an exception in dbgheap.c in the following
place:
>
> /* Error if freeing incorrect memory type */
> _ASSERTE(pHead->nBlockUse == nBlockUse);
>
>(line 1051 in my version).
>
>It happens while I am freeing memory that was used by one list (CPtrList
>derivative). The code looks like this:
First, your if statement:
> if( (CRowHeader*)GetNext( pos1 ) )
is using a completely useless cast.
You don't provide enough information to diagnose your problem. It's likely
that you'll throw this assertion if you're adding objects to the list that
don't need to be deleted. Maybe you've added a pointer to a global object
which donesn't need to be deleted, and that'll cause your problem.
If you showed how you populated the list (that is, where do the pointers you're
deleting actually come from?), that might be helpful.
Maybe your destructor is really goofy, or you have some other memory-overwrite
problem elsewhere in your application.
At any rate, I think your loop is very convoluted--you should try to write it
with a little more clarity:
POSITION pos;
while (GetHeadPosition())
{
CRowHeader* p = (CRowHeader*) list.RemoveHead();
delete p;
}
is functionally identical, but a far clearer and more efficient.
.B ekiM
http://www.nwlink.com/~mikeblas/
I'm afraid I've become some sort of speed freak.
These words are my own. I do not speak on behalf of Microsoft.
Mike Blaszczak -- mikeblas@nwlink.com
Monday, October 28, 1996
[Mini-digest: 2 responses]
At 10:14 10/28/96 +0900, John Young wrote:
>> for( pos1 = GetHeadPosition(); ( pos2 = pos1 ) != NULL; )
>> {
>> if( (CRowHeader*)GetNext( pos1 ) )
>> {
>> pCur = (CRowHeader *)GetAt( pos2 );
>> RemoveAt( pos2 );
>> delete pCur; //<<<--- HERE COMES THE ASSERTION
>> }
>> }
>The first time through the loop pos2 is uninitialised. I always use this...
No, it isn't. It is initialized by the contorlling statement of the for() loop,
which includes an assignment. As the for() loop starts, the language dictates
that:
1. the initialization expression is evaluated
2. the controlling expression is evaluated
if the controlling expression is zero, exit the loop
3. execute the body of the loop once
4. exectue the increment expression
5. go to step two
where, in
for(ex1; ex2; ex3)
ex1 is the initialization expression, ex2 is the controlling expression,
and ex3 is the increment expression.
This has been the way the language has worked since C. It isn't even one of the
hairy things that the C++ unstandard has given us.
Try this little ditty in the debugger to make sure you feel good about it:
#include
void main()
{
int x = 0;
int y = 37;
printf("x = %d, y = %d\n", x, y);
for (x = 1; (y = x) != 10; x++)
{
printf("x = %d, y = %d\n", x, y);
}
}
.B ekiM
http://www.nwlink.com/~mikeblas/
I'm afraid I've become some sort of speed freak.
These words are my own. I do not speak on behalf of Microsoft.
-----From: Mast-CBT
At 11.46 24/10/96 +0200, you wrote:
>Environment: Win95,VC4.2
>
>Hi!
>
>Executing an application I got an exception in dbgheap.c in the following
place:
>
> /* Error if freeing incorrect memory type */
> _ASSERTE(pHead->nBlockUse == nBlockUse);
>
>(line 1051 in my version).
>
>It happens while I am freeing memory that was used by one list (CPtrList
>derivative).
>The code looks like this:
>
>void CRowHeaderList::RemoveAll()
>{
> POSITION pos1,pos2;
> CRowHeader * pCur;
>
> for( pos1 = GetHeadPosition(); ( pos2 = pos1 ) != NULL; )
> {
> if( (CRowHeader*)GetNext( pos1 ) )
> {
> pCur = (CRowHeader *)GetAt( pos2 );
> RemoveAt( pos2 );
> delete pCur; //<<<--- HERE COMES THE ASSERTION
> }
> }
>
>}
>
>pCur is of Type CRowHeader class.It has an empty constructor.
>
>Stack at the moment of assertion looks like this:
>
>_free_dbg(void * 0x01256470, int 1) line 970 + 13 bytes
>operator delete(void * 0x01256470) line 282 + 12 bytes
>??3CObject@@SGXPAX@Z + 9 bytes
>CRowHeader::`scalar deleting destructor'() + 39 bytes
>CRowHeaderList::RemoveAll() line 93 + 35 bytes
>
>I have no any idea of where error could be.Have you?
>
>Thanks in advance,
>Svetlana Guljajeva
>
>
>
>
>-----------------------------------------
>**svetlana@assert.ee**
>//**Assert Ltd.**\\
>//****Tallinn****\\
>//****Estonia****\\
>
>
>
There is probably an error in your code. You can't delete a pointer that
don't contain an object.
void CRowHeaderList::RemoveAll()
{
POSITION pos1,pos2;
CRowHeader * pCur;
for( pos1 = GetHeadPosition(); ( pos2 = pos1 ) != NULL; )
{
if( (CRowHeader*)GetNext( pos1 ) )
{
pCur = (CRowHeader *)GetAt( pos2 );
RemoveAt( pos2 );
// Can't delete a pointer that don't contain any object !!!!!!!
delete pCur; //<<<--- HERE COMES THE ASSERTION
// ----------------------------------------------------
}
}
}
So, before you assign
'pCur = (CRowHeader *)GetAt( pos2 )'
the pointer must contain a CRowHeader object.
I hope this can help you!
Bye
Mast
Sundar Narasimhan -- sundar@ai.mit.edu
Wednesday, October 30, 1996
This is one of our developers' favorite (or least favorite) gripes
with VC++. Make sure you are linking with the right DLL's and all your
files are compiled with the same switches. And make sure you read the
document for LNK4098 and understand why things are the way they are.
Hi!
Executing an application I got an exception in dbgheap.c in the following place:
/* Error if freeing incorrect memory type */
_ASSERTE(pHead->nBlockUse == nBlockUse);
(line 1051 in my version).
It happens while I am freeing memory that was used by one list (CPtrList
derivative).
The code looks like this:
void CRowHeaderList::RemoveAll()
{
POSITION pos1,pos2;
CRowHeader * pCur;
for( pos1 = GetHeadPosition(); ( pos2 = pos1 ) != NULL; )
{
if( (CRowHeader*)GetNext( pos1 ) )
{
pCur = (CRowHeader *)GetAt( pos2 );
RemoveAt( pos2 );
delete pCur; //<<<--- HERE COMES THE ASSERTION
}
}
}
pCur is of Type CRowHeader class.It has an empty constructor.
Stack at the moment of assertion looks like this:
_free_dbg(void * 0x01256470, int 1) line 970 + 13 bytes
operator delete(void * 0x01256470) line 282 + 12 bytes
??3CObject@@SGXPAX@Z + 9 bytes
CRowHeader::`scalar deleting destructor'() + 39 bytes
CRowHeaderList::RemoveAll() line 93 + 35 bytes
I have no any idea of where error could be.Have you?
Thanks in advance,
Svetlana Guljajeva
-----------------------------------------
**svetlana@assert.ee**
//**Assert Ltd.**\\
//****Tallinn****\\
//****Estonia****\\
| Вернуться в корень Архива
|