C++ destructor explicit call

A681d4d6a976c15ab7d4db1126333a0a
0
amnonman 101 Jul 03, 2006 at 06:25

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

12 Replies

Please log in or register to post a reply.

6d318bb67270aa12b325e2cd7b64ff7a
0
pater 101 Jul 03, 2006 at 06:44

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
A681d4d6a976c15ab7d4db1126333a0a
0
amnonman 101 Jul 03, 2006 at 06:57

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?

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Jul 03, 2006 at 07:14

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.

B7568a7d781a2ebebe3fa176215ae667
0
Wernaeh 101 Jul 03, 2006 at 08:38
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

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Jul 03, 2006 at 09:03

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

A681d4d6a976c15ab7d4db1126333a0a
0
amnonman 101 Jul 03, 2006 at 10:23

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?

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Jul 03, 2006 at 10:31

@amnonman

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

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.

A681d4d6a976c15ab7d4db1126333a0a
0
amnonman 101 Jul 03, 2006 at 10:42

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.

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.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Jul 03, 2006 at 10:46

Create an object that wraps the class you can’t change.

template <typename T>
class wrapper: public Destroyable {
public:
    T myData;
    virtual ~wrapper (); {}
};
340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Jul 03, 2006 at 11:28

loose the ; after \~wrapper() :)

A681d4d6a976c15ab7d4db1126333a0a
0
amnonman 101 Jul 03, 2006 at 11:47

Thanks Reedbeta.
I will try this :)

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Jul 03, 2006 at 13:09

Lol…you’re right of course .oisyn.
Serves me right after pointing out Wernaeh’s syntax error :)