destructor not being called (Resolved)
-
Windows 7, Visual Studio, C++, MFC dialog A MFC dialog calls _beginthreadex and starts procedure Start_Server_As_Thread as a new thread. That procedure instantiates class C_Server_Thread then calls a method that loops until an event indicates time to exit. That class creates a new instance of C_Log_Writer to write information to a log file. The appropriate event is set, and the main loop exits. Immediately on regaining control, procedure Start_Server_As_Thread deletes the class with:
delete mp_C_Server_Thread;
The destructor of that class is not called. The destructor contains the code
delete mp_C_Log_Writer;
which does not get run resulting in a memory leak. I was under the impression that explicitly deleting an instance of a class forced the destructor to be called. What should I do to get that destructor called? In the code that detects said event I can add a line to delete the logger class. Still, the question will remain, why is the destructor not called? Edit: Just for completeness, a silly mistake that I looked right at several times before finally stepping through the code one step at a time.
if( mp_C_Log_Writer == NULL )
{
delete mp_C_Log_Writer;
mp_C_Log_Writer = NULL;The == should have been !=. Lesson learned again, always step through every line of code with the debugger at least once. Sorry to trouble anyone over this.
Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com
-
Windows 7, Visual Studio, C++, MFC dialog A MFC dialog calls _beginthreadex and starts procedure Start_Server_As_Thread as a new thread. That procedure instantiates class C_Server_Thread then calls a method that loops until an event indicates time to exit. That class creates a new instance of C_Log_Writer to write information to a log file. The appropriate event is set, and the main loop exits. Immediately on regaining control, procedure Start_Server_As_Thread deletes the class with:
delete mp_C_Server_Thread;
The destructor of that class is not called. The destructor contains the code
delete mp_C_Log_Writer;
which does not get run resulting in a memory leak. I was under the impression that explicitly deleting an instance of a class forced the destructor to be called. What should I do to get that destructor called? In the code that detects said event I can add a line to delete the logger class. Still, the question will remain, why is the destructor not called? Edit: Just for completeness, a silly mistake that I looked right at several times before finally stepping through the code one step at a time.
if( mp_C_Log_Writer == NULL )
{
delete mp_C_Log_Writer;
mp_C_Log_Writer = NULL;The == should have been !=. Lesson learned again, always step through every line of code with the debugger at least once. Sorry to trouble anyone over this.
Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com
Is
mp_C_Server_Thread
of typeC_Server_Thread*
, or a base class? If it is abase class pointer, and the base class does not have a virtual destructor, the derived class destructor will not be called. You are right, callingdelete
on a pointer will call the pointer type's destructor, if any, but without more code to look at it's very hard to say what the problem might be. For instance, are you absolutely sure that Start_Server_As_Thread does regain control, and that the delete call is executed? -
Is
mp_C_Server_Thread
of typeC_Server_Thread*
, or a base class? If it is abase class pointer, and the base class does not have a virtual destructor, the derived class destructor will not be called. You are right, callingdelete
on a pointer will call the pointer type's destructor, if any, but without more code to look at it's very hard to say what the problem might be. For instance, are you absolutely sure that Start_Server_As_Thread does regain control, and that the delete call is executed?Here is the procedure that is started as the new thread. It instantiates a class then runs the main method of that class.
unsigned int __stdcall Start_Server_As_Thread( void * p_void_pointer )
{
C_Server_Thread *mp_C_Server_Thread = NULL;
WCHAR m_log_file_text[ MAX_LOG_STRING_LENGTH ];mp\_C\_Server\_Thread = new C\_Server\_Thread( p\_void\_pointer ); // Call the main method of the class. When this method returns, // the thread exits. mp\_C\_Server\_Thread->Main\_Thread\_Loop(); delete mp\_C\_Server\_Thread; mp\_C\_Server\_Thread = NULL; // We are all done. End this thread. \_endthreadex( 0 ); return 0;
}
That class is declared as follows
class C_Server_Thread
{...}The class it creates is declared:
class C_TCP_API_Server
{...}Class C_Server_Thread manages all the overhead and communications between the main app and the thread. It instantiates C_TCP_API_Server, which does all the low level work of establishing a TCP/IP link with the client and sending the data. Does that provide any useful information? Edit: I continue to work this and am not certain where the problem is, but am becoming more certain that PEBKAC (Problem Exists Between Keyboard And Chair). It is looking more and more like a logic error in how I end this thing. Class C_Server_Thread could be in any of several states when it gets the event to exit. (Not connected to client, connected to client, sending data, etc) I need to work over the logic of what should be done for each state to ensure an orderly shutdown, not to mention complete shutdown.
Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com