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 ChenIf 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 Youngwrote: >> 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****\\
| Вернуться в корень Архива |