我有一个c ++控制台看起来像这样的应用程序:
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()
本质上是一个循环,一直运行直到SomeObj::Stop()
被调用。当我执行CTRL + C时,我可以看到应用程序在退出之前正确删除obj
。但是,当我单击控制台窗口上的关闭按钮时,我发现obj
未被正确删除。
进一步的调试表明,实际上调用了closeHandler,但不知道obj
不会被删除。奇怪的是,如果我在return 0
行放置一个断点并尝试关闭控制台窗口,我最终会遇到该断点并看到obj
已被删除。
我在这里做错了什么?有没有更好的方法在控制台窗口关闭事件上释放内容?
答案 0 :(得分:2)
我猜你的closeHandler()例程从未实际完成,因为它正在等待obj变为0(可能你的意思是“NULL”或C ++ 11风格的“nullptr”)。删除对象不会将指针设置为null。老实说,我不确定为什么会有这个循环呢?
答案 1 :(得分:1)
我建议您的处理程序实际上不删除该对象。您将obj指定为全局,但实际上并未在closeHandler中将其删除。也许像以下那样......
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
{
if (CTRL_CLOSE_EVENT == dwCtrlType)
{
if (NULL != obj)
{
delete obj;
obj = NULL
}
}
}
答案 2 :(得分:1)
是的,有一种方法不需要您手动调用delete或将指针设置为null。使用像std::unique_ptr
这样的智能指针。您也不必等待删除该对象,因为一旦Execute
完成并且main
返回,清理将得到妥善处理。
#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();
}