Jump to content


C++ destructor explicit call


12 replies to this topic

#1 amnonman

    New Member

  • Members
  • Pip
  • 9 posts

Posted 03 July 2006 - 06:25 AM

Hi,
Can someone think of a way to call a destructor for a class not by calling the delete keyword?
Maybe a way to get a pointer to the destructor function, and pass it as a callback?
thanks,
Amnon

#2 pater

    Valued Member

  • Members
  • PipPipPip
  • 117 posts

Posted 03 July 2006 - 06:44 AM

It is possible to call the destructor directly. This is sometimes even required, if you want to clean up an object without releasing it's memory, i.e. because you have written your own memory allocation algorithm.

class A

{

void* x;

public:

 A(){x=malloc(1000);};

 ~A(){free(x);};

};

//Further down


A* a= new A();

a->~A(); //Frees x, but doesn't free the space for a



#3 amnonman

    New Member

  • Members
  • Pip
  • 9 posts

Posted 03 July 2006 - 06:57 AM

Thanks Peter,
What I really need is calling the destructor through a pointer, since I don't know what object was allocated on a certain memory address, but i do have the address and can have a pointer to a fuction assosiated with it (hopfully the right destructor).
so what I meant to really ask is - can you hold a pointer to an object's destructor function?

#4 Reedbeta

    DevMaster Staff

  • Administrators
  • 5307 posts
  • LocationBellevue, WA

Posted 03 July 2006 - 07:14 AM

There is a syntax for C++ pointers to member functions, but unfortunately it doesn't allow to take the address of the destructor as far as I know. However, you can create another member function that does nothing but call the destructor directly as shown in pater's post.
reedbeta.com - developer blog, OpenGL demos, and other projects

#5 Wernaeh

    Senior Member

  • Members
  • PipPipPipPip
  • 368 posts

Posted 03 July 2006 - 08:38 AM



typedef void (*DestroyCall)(void *placement);


class MyClass

{


          static void DestroyMe(void *placement)

          {

                if (placement)

                         ((MyClass*)placement)->~MyClass();

          }

}


void DestroyAny(void *placement, DestroyCall destroy)

{

          destroy(placement);

}


Not a very good solution, obviously, since it is not type safe.

Dependant on your setup, another - better - way would be to make the destructor virtual, and add a unique destroy function for each of your root classes... But I guess you know this already :)

Finally, some template magic may also help - alongside virtual destructors, that is:


template <typename T>

    void Destroy<T>(T *object)

{

         T->~T();

}


Cheers,
- Wernaeh
Some call me mathematician, some just call me computer guy. Yet, I prefer the term professional weirdo :)

#6 Reedbeta

    DevMaster Staff

  • Administrators
  • 5307 posts
  • LocationBellevue, WA

Posted 03 July 2006 - 09:03 AM

A minor quibble:
when declaring the function template Destroy, you oughtn't to declare it as Destroy<T>, that syntax is only necessary when referring to the function later. :)
reedbeta.com - developer blog, OpenGL demos, and other projects

#7 amnonman

    New Member

  • Members
  • Pip
  • 9 posts

Posted 03 July 2006 - 10:23 AM

Thanks for your answers.
The thing is, I can't change the classs of the objects I want to destroy and I don't know their types.
All I want is to free their memory (I do have their address). I want to make sure the are destroyed legaly so if they have a destructor it should be called.
So bassicaly I have an address of an unknown class and i want to free it. I can save some information when creating the class (like ths destructor function poiter - if I could) and assosiate it later when the destruction is needed.
So let me rephrase the question:
Is it possible to free an object's memory of an unknown class given it's address alone, with the help of some hint or callback saved in advance?
hope I managed to clarify my problem...:wacko:

The ugly direction for solution I thought of, was to look for the offset of the destructor function in the function table, and use it later.
I know that the constructor function is always the first function in the table, what can you say about the destructor? If this could work, what about virtual destructors?

#8 Reedbeta

    DevMaster Staff

  • Administrators
  • 5307 posts
  • LocationBellevue, WA

Posted 03 July 2006 - 10:31 AM

amnonman said:

I know that the constructor function is always the first function in the table, what can you say about the destructor? If this could work, what about virtual destructors?

Unfortunately, that's not true. The constructor isn't a virtual function, so it wouldn't even appear in the vtable. As for the other functions, their order is defined by the compiler, so there's generally no way to get this information.

amnonman said:

Is it possible to free an object's memory of an unknown class given it's address alone, with the help of some hint or callback saved in advance?

I would advise you to create a base class:
class Destroyable {
public:
    virtual ~Destroyable () {}
};

and derive every class which you want to store in this data structure from Destroyable. Then, you can simply cast your pointer to Destroyable* and invoke the destructor that way. This will force the destructor to be at the same location in the vtable in all the classes, so as to allow the virtual call.
reedbeta.com - developer blog, OpenGL demos, and other projects

#9 amnonman

    New Member

  • Members
  • Pip
  • 9 posts

Posted 03 July 2006 - 10:42 AM

Quote

I know that the constructor function is always the first function in the table,
Yes you are right, I got confused. I was refereing to the pointer of the vtable that resides in the same location not the constructor pointer.

Quote

I would advise you to create a base class:
That could work, but this is still involving changing the class. The classes I have could come for example from a lib or dll that I don't have their source code or can't rebuild.

#10 Reedbeta

    DevMaster Staff

  • Administrators
  • 5307 posts
  • LocationBellevue, WA

Posted 03 July 2006 - 10:46 AM

Create an object that wraps the class you can't change.
template <typename T>
class wrapper: public Destroyable {
public:
    T myData;
    virtual ~wrapper (); {}
};

reedbeta.com - developer blog, OpenGL demos, and other projects

#11 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 03 July 2006 - 11:28 AM

loose the ; after ~wrapper() :)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#12 amnonman

    New Member

  • Members
  • Pip
  • 9 posts

Posted 03 July 2006 - 11:47 AM

Thanks Reedbeta.
I will try this :)

#13 Reedbeta

    DevMaster Staff

  • Administrators
  • 5307 posts
  • LocationBellevue, WA

Posted 03 July 2006 - 01:09 PM

Lol...you're right of course .oisyn.
Serves me right after pointing out Wernaeh's syntax error :)
reedbeta.com - developer blog, OpenGL demos, and other projects





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users