简体   繁体   中英

Deallocating memory on console close event

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM