在控制台关闭事件上释放内存

时间:2013-06-25 19:42:34

标签: c++ windows visual-studio-2010 winapi visual-c++

我有一个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已被删除。

我在这里做错了什么?有没有更好的方法在控制台窗口关闭事件上释放内容?

3 个答案:

答案 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();
}
相关问题