I have c++ console an application that looks something like this:
SomeObj* obj;
BOOL WINAPI closeHandler(DWORD cEvent)
{
obj->Stop();
while( obj != 0 )
{
Sleep(100);
}
return TRUE;
}
int main(int argc, char* argv[])
{
SetConsoleCtrlHandler( (PHANDLER_ROUTINE)SignalHandler, true );
obj = new SomeObj();
obj->Execute();
delete obj;
return 0;
}
SomeObj::Execute()
is essentially a loop that keeps running until SomeObj::Stop()
is called. When I do a CTRL+C, I can see that the application deletes obj
properly before exiting. However, when I click on the close button on the console window, I find out that obj
doesn't get deleted properly.
Further debugging showed that closeHandler is actually called, but somehow obj
just doesn't get deleted. Strangely, if I put a breakpoint on the return 0
line and try to close the console window, I end up hitting that breakpoint and see that obj
was deleted.
What am I doing wrong here? Is there a better way to deallocate stuff on a console window close event?
I'm guessing your closeHandler() routine never actually completes because it is waiting for obj to become 0 (presumably you mean "NULL" or C++11-style "nullptr" here). Deleting an object does not set pointers to it to null. I'm honestly not sure why it has this loop at all?
I would suggest that your handler isn't actually deleting the object. You specify obj as a global but do not actually delete it in the closeHandler. Maybe something like the following...
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
{
if (CTRL_CLOSE_EVENT == dwCtrlType)
{
if (NULL != obj)
{
delete obj;
obj = NULL
}
}
}
Yes, there is a way that doesn't require you to manually call delete or set the pointer to null. Use a smart pointer like std::unique_ptr
. You also don't have to wait for the object to be deleted since cleanup will be handled properly once Execute
finishes and main
returns.
#include <iostream>
#include <memory>
// sample test object that oeprates as described in your question.
struct Object
{
Object() : running_(true) {}
~Object()
{
std::cout << "Object deleted" << std::endl;
}
void Stop() { running_ = false; }
void Execute() { while(running_ == true); }
bool running_;
};
// incredibly smart pointer!
std::unique_ptr<Object> obj;
BOOL WINAPI closeHandler(DWORD)
{
// We need to call stop on the object if it exists
// use appropriate locks for multithreaded environment
if(obj != nullptr)
{
obj->Stop();
// no need to wait
}
return TRUE;
}
int main()
{
SetConsoleCtrlHandler( closeHandler, true );
// Allocate the object and execute
obj.reset(new Object());
obj->Execute();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.