can't delete? assert fails

Started by
5 comments, last by hplus0603 19 years, 7 months ago
I've got a generic class to handel creating a window with winAPI. Children of this class only have to define their MsgProc function, (and a VERY small constructor/destructor) and can be created and removed in one line each, (new/delete an instance of the class.) I use a static member function as my MsgProc and have that one look through a list of instances of the WindowHandeler class to see who it pass it on to. This all seems to work the problem is when I catch an exception in this static MsgProc I want to delete the instance that caused the exception so I don't try to run code that doesn't work. If I do this I get an assertion failed in vc++ in the delete operator (dbgdel.cpp(52)): /* verify block type */ _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); from googleing this I gather it usualy happens if your trying to free memory allocated in a dll from the exe or vice versa... I'm not makeing any dlls and the windows ones shouldn't be trying to free my classes on me... any way to fix this? On a side note it'd probably be a good idea to kill the whole program at this point should I just exit(1) and ignore the memory I've new'ed hoping windows can clean it up... probably a bad idea right?
Advertisement
Quote:Original post by drdlord
This all seems to work the problem is when I catch an exception in this static MsgProc I want to delete the instance that caused the exception so I don't try to run code that doesn't work. If I do this I get an assertion failed in vc++ in the delete operator (dbgdel.cpp(52)):

/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

from googleing this I gather it usualy happens if your trying to free memory allocated in a dll from the exe or vice versa... I'm not makeing any dlls and the windows ones shouldn't be trying to free my classes on me...

any way to fix this?


what exception is being thrown? perhaps you should post your types & relevant code.

Quote:Original post by drdlord
On a side note it'd probably be a good idea to kill the whole program at this point should I just exit(1) and ignore the memory I've new'ed hoping windows can clean it up... probably a bad idea right?


Yes that is a bad idea.
Quote:Original post by drdlord
from googleing this I gather it usualy happens if your trying to free memory allocated in a dll from the exe or vice versa...


It also happens if you're writing past the end of arrays or if you're deleting stuff that's already been deleted before.
Quote:Original post by snk_kid
Quote:Original post by drdlord
On a side note it'd probably be a good idea to kill the whole program at this point should I just exit(1) and ignore the memory I've new'ed hoping windows can clean it up... probably a bad idea right?


Yes that is a bad idea.


I was going over some code an intern had written for us once. MFC application, and inside the worker thread that was parsing script execution, if there was an error I found this code (comments included):

m_mainWnd.PostMessage (WM_USER_ERROR, pErrMessage);
exit(-1); // exit gracefully

I almost peed my pants laughing.
Quote:Original post by snk_kid

what exception is being thrown? perhaps you should post your types & relevant code.


I'm throwing a custom exception, that part works fine it catchs properly and displays the proper error to the user. The problem comes when I try to delete the instance of WindowHandeler that caused the exception, I delete the same pointer to WindowHandeler that I used to run the function that threw the exception. So the pointer is valid. The error I'm getting is an assertion failed, (on the given line in dbgdel.cpp, part of the delete operator) I can use the call stack to see the line in my code that called this and it's where I'm trying to delete the instance that threw the exception.

Quote:
Quote:Original post by drdlord
On a side note it'd probably be a good idea to kill the whole program at this point should I just exit(1) and ignore the memory I've new'ed hoping windows can clean it up... probably a bad idea right?


Yes that is a bad idea.


ok then how can I ignore the remaining msgs in the queue and postQuitMessage() I don't want to translate and dispatch them because they might reference a now defunct class, (If I can get the program to exit gracefully without calling on the defunct class my destructors should automaticly clean everything up)
ok I still don't know why I couldn't delete but I've avoided the problem by using this instead of delete:
// Clear the message loopMSG msg;ZeroMemory(&msg, sizeof(msg));    while(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE));PostQuitMessage(0);

then when I quit all the destructors are called and everything is cleaned up
Just because you could make a virtual function call doesn't mean the pointer is valid. Add logging for each window constructor and destructor called where you print the "this" value. Then add logging in the exception catch to print what the pointer value is. You might find that one of two things is true:

1) you see a destructor, and THEN you see a message for the window

2) you see a window pointer which you haven't seen a constructor for


However, there are some other possibilities:

3) because messages are sent when you delete a window handle, you get more than one dispatch and thus possibly more than one delete for the same window

4) your memory block, while the right pointer, has gotten smashed, either before or after the actual block, corrupting heap data structures


Actually, if I were a betting man, my money would be on 3).

BTW: if you want to easily dispatch to an object, you could use SetWindowLong() to set the USER value to be a direct pointer to your window class. Do this inside WM_NCCREATE (which is the first message sent to a window); pass the actual pointer as part of the user data at the end of the window creation struct.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement