If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register or Login
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

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:

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.

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.

(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.

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).

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.