How to find out if the object is dynamic and was created on the heap?
I have a pointer to an object and I need to call delete operator only if the object was created on the heap. Is there any way to programmatically define this?
Re: How to find out if the object is dynamic and was created on the heap?
Originally posted by olstar
I have a pointer to an object and I need to call delete operator only if the object was created on the heap. Is there any way to programmatically define this?
No.
Why not let the module that allocated the pointer be responsible for deleting the pointer?
If you're working with objects of a class you authored, then include a member variable like m_bCreatedOnHeap. Set it to your preferred default in the ctor, and then override it in your code when the object is created (if it's created inconsistently with the default).
Then, in the dtor, test for its value and condition a "delete this;" on it:
Code:
class CMyClass{
...
BOOL m_bCreatedOnHeap;
...
};
CMyClass::CMyClass() : m_bCreatedOnHeap(TRUE)
{
...
}
CMyCLass::~CMyCLass()
{
if (m_bCreatedOnHeap) delete this;
}
// in code
CMyClass cmy;
cmy.m_bCreatedOnHeap=FALSE; // must overrride since it's on the stack
CMyClass* pcmy = new CMyClass; // default is ok as it is
First for Mike:
If you dynamically allocate the class, how will the destructor get called so it can delete itself? If you call delete on the ptr there will be a stack overflow since delete calls the destructor inside the destructor, so if its dynamically allocated, it will call the destructor over and over...
The best solution for this to to overload the delete operator for the class.
Do as mike suggested and put a boolean in the class.
also in the class do this:
But in general, there is no way to determine that, if given a pointer, whether it points to a dynamically created object. This is well explained with a whole chapter dedicated to this in Scott Meyers "More Effective C++".
Maybe the OP should tell us what they are trying to accomplish and why determining whether an object was or was not created dynamically needs to be done. Usually, doing such things are a sign of a bad design.
I agree .. When one tries to do such thing and sees that the only solution to do that is such hacks, there is some problem somewhere and things start getting ugly.
I would say the same about runtime class information too.
It would be a good exercise to try to avoid it as much as possible. You may end up in a neater version..
The only problem with doing things like this "hack" as you call it, otherwise known as overloading the delete operator, is that it makes the code too confusing for most out there, run-time type identification is also confusing for most.
However there are more then enough reasons to use these things in your programs. COM is a good example of why you need RTTI. Granted I'll give Paul credit here cause COM is awfully designed.
Polymorphism and operator overloading is a necessity though in many application and many do not realize how much easier their lives would be it they would just buckle down and learn it instead of fearing what they don't understand.
Its the deference between makeing 6 figures and only 5, so its worth the time...
Originally posted by oktronic
First for Mike:
If you dynamically allocate the class, how will the destructor get called so it can delete itself? If you call delete on the ptr there will be a stack overflow since delete calls the destructor inside the destructor, so if its dynamically allocated, it will call the destructor over and over...
Of course you're correct. The destructor would not be called and if it were there would be a terrible recursion (if indeed it was possible to call the destructor more than once considering that the "this" pointer would be invalid).
Rather than overloading the delete operator, however, it might be better to define a member function called something like DeleteMeIfNeeded(), which could be called on any object. It also makes sense to check the "this" pointer, so you might have code like
I seem to recall that this is the technique used in MFC to pass CException's by pointer, and to ensure that the CExceptions are deleted if needed, and a check at http://www.microsoft.com/msj/0799/c/c0799.aspx by Paul DiLAscia confirms this.
I also agree that it's getting awfully close to a hack.
-Mike
edit: I just remembered that the debug version sets "this" to something odd like 0xCDCDCDCD, so the check against NULL won't work.
Last edited by MikeAThon; September 29th, 2003 at 07:33 PM.
I agree that it is better to not need to determine whether an object was allocated on the stack or the heap and to either not delete itself or delete itself based on where it has been allocated.
Note that many MFC classes have a m_bAutoDelete member that determines whether the object deletes itself.
(if indeed it was possible to call the destructor more than once considering that the "this" pointer would be invalid).
The destructor is the first thing called when you delete, so the "free" would never be reached to invalidate the pointer.
While I have no idea why this guy wishes to do this, there are reasons that you might wish do check something like this.
I can think for several, but I'll give you a quick breakdown of one that popped in my head.
you have a std::map.
You have a dynamic list passed back from some obnoxious "windows" like api function which expects you to delete the memory it allocated...
You have a bunch of static objects that you wish to sort and operate on with the returned dynamic ones.
you put them in your map and run a loop to operate on them...
you then have to run another loop and operate on those aswell...
The performance is dropped by the second loop, especially if you need to a windows pump so it doesn't lock up your program. Cause both loops will need it if you have length operations or millions of elements...
Then you need to delete the memory which is another loop which also requires a "anti-locking" mechinism if there a lots of elemets.
if you approach the problem the same way this guy is, then you can delete each of the elements after you operate on them all in the same loop, so there is no need for the second or third loop.
While you say "but the performance hit is minimal", sure it is, for only 1000, maybe 10000 but on 1000000? 100000000? you can save time by deleteing them as you go. And since the sorted list has pointers for both, you don't have to worry about whether it was a static or dynamic with this approach.
Its not a hack, just a performance boost, it cuts a little un-necessary fat out of your program. If you make very intensive programs as I do, then you need to cut these chunks out so your program doesn't look like something MS made...
However, I have no idea why he's doing it this way, such things may not be necessary for him and in someways may slow him down... hopefully he'll find another way.
Last edited by oktronic; September 29th, 2003 at 07:48 PM.
OK, you convinced me and I'm back on the non-hack side And although MFC perhaps shouldn't be held up as an example, as Sam points out there are many MFC classes that have a m_bAutoDelete member that determines whether the object deletes itself (other than the CException class I originally mentioned).
It would be nice to hear from the OP.
-Mike
PS to mick_2002: I suppose that "odd" was a poor choice of words <g>
See the attached gobal function IsDynamic(void* pPointer), which returns true if the pPointer was created on the heap. The idea is to get a pointer to the heap start and compare it to pPointer. In Visual C++ 5.0 the stack memory allways lies below the heap memory.
The function _heapwalk(...) in <malloc.h> allows you to get a pointer to the first heap element. In IsDynamic(...) these two pointers are compared and thats all.
Comments to your problem:
===================
As described in all other comments above I believe that it is a very bad programming style what you are doing. Normally you should know when to use dynamic or static object. The only usefull usage of IsDynamic(...) is to ensure that only dynamic pointers are added to another object handling and destroying them. This was the only reason for me to develop this check, but maybe it will solve your problem too.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.