Introduction
I have seen too many people trying to determine if an object is allocated on the heap or not. It can help to create a garbage collection or find if an object with a reference counter should automatically call the delete
operator or not when its counter reaches zero.
You can search in the web for many articles dealing with this but most of them have the problem that they rely on how the memory is initialized or they aren't thread safe.
But with the help of thread local storage that the operating system provides and a very rarely used stuff that MFC has, we can deal with this problem easily. MFC gives us some classes to store information private for each thread with the THREAD_LOCAL
macro (you can see more in afxtls.cpp and afxtls_.h in the MFC source code). So taking advantage of this macro I created an internal class that is used when the object is constructed and when it is allocated on the heap, by overriding the new
and delete
operators.
The new
operator of the base class initializes the internal detector of the thread that is currently allocating the object if it was not done previously and then sets a flag indicating that the object is being allocated on the heap. Later, when the constructor is called, the base class checks if this flag is on or not to determine if the object is on the heap or not.
Using the code
The only thing you must do to detect if your objects are allocated dynamically or not is to derive them from CDynamicObjectBase
and then call the IsAllocatedOnDynamicMemory
function anywhere you wish.
To use the code in your project, add the DynamicObjectBase.cpp and DynamicObjectBase.h files to your project and add CDynamicObjectBase
as a base class for your classes.
class yourg_class : public CDynamicObjectBase
{
...
In the sample application you will see a class named CMyCustomObject
that has a function that prints where it was allocated.
Known issues
- To make the code MFC-independant you must create a copy of the functionality of most classes and functions located in afxtls_.h and afxtls.cpp. I did it and it is not difficult for an experienced programmer.
- There is a function named
DynamicObjectBaseReset
that resets the internal state of the detector in the thread context of the caller. I didn't test what happens if an exception is thrown during the object's constructor. I think nothing happens because CDynamicObjectBase
's constructor is called before any derived constructors (it is the base class), or you can modify the code to catch exceptions, but for any case the function is provided.
As a final note, suggestions for improvements are welcome.
My name is Mauro Leggieri. I am 30 year-old, married and have a child.
I am a system engineer (UTN university) and am being programming for more than 20 years from the C64 to the PC and some microcontrollers.
Mostly of my time, I program games for Windows.
Soon, my site http://www.mauroleggieri.com.ar