May 21st, 2004

Do you know when your destructors run? Part 2.

Continuing from yesterday, here’s another case where you have to watch your destructors. Yesterday’s theme was destructors that run at the wrong time. Today, we’re going to see destructors that don’t run at all!

Assume there’s an ObjectLock class which takes a lock in its constructor and releases it in its destructor.

DWORD ThreadProc(LPVOID p)
{
  ... do stuff ...
  ObjectLock lock(p);
  ... do stuff ...
  return 0;
}

Pretty standard stuff. The first batch of stuff is done without the lock, and the second batch is done inside the lock. When the function returns, the lock is automatically released.

But suppose somebody adds a little code to this function like this:

DWORD ThreadProc(LPVOID p)
{
  ... do stuff ...
  ObjectLock lock(p);
  ...
  if (p->cancelled) ExitThread(1);
  ...
  return 0;
}

The code change was just to add an early exit if the object was cancelled.

But when does that ObjectLock destructor run?

It runs at the return statement, since that’s when the lock goes out of scope. In particular, it is not run before you call ExitThread.

Result: You left an object locked permanently.

You can imagine how variations on this code could lead to resource leaks or other problems.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.