Delete without calling destructor?

  • Thread starter Tomás Ó hÉilidhe
  • Start date
T

Tomás Ó hÉilidhe

"delete" does two things:

1) Invokes the destructor
2) Deallocates the memory

We can manually invoke the destructor with:

p->~T();

But is there any way to manually deallocate the memory without invoking
the destructor? Something like "placement delete" perhaps? I'd be using
it where I'd be continuously constructing and destroying an object:


T *const p = new T;

p->~T();

::new(p) T;

p->~T();

::new(p) T;

p->~T();

::new(p) T;

p->~T();

::new(p) T;

p->~T();

SomeSortOfPlacementDelete(p); /* Just de-allocate, don't destruct */
 
A

Alf P. Steinbach

* Tomás Ó hÉilidhe:
"delete" does two things:

1) Invokes the destructor
2) Deallocates the memory

We can manually invoke the destructor with:

p->~T();

But is there any way to manually deallocate the memory without invoking
the destructor? Something like "placement delete" perhaps? I'd be using
it where I'd be continuously constructing and destroying an object:


T *const p = new T;

p->~T();

::new(p) T;

p->~T();

::new(p) T;

p->~T();

::new(p) T;

p->~T();

::new(p) T;

p->~T();

SomeSortOfPlacementDelete(p); /* Just de-allocate, don't destruct */

If you know the exact size used for the original allocation you could
perhaps use ::eek:perator delete.

However I recommend, instead, to not do what is most likely premature
optimization.

And anyway, if measurements show you really need to avoid those
"needless" allocations and deallocations, define operator new and
operator delete for the class, and/or use an allocator more suitable for
this particular situation than the built-in one.


Cheers, & hth.,

- Alf
 
T

Tomás Ó hÉilidhe

Alf P. Steinbach:
If you know the exact size used for the original allocation you could
perhaps use ::eek:perator delete.

However I recommend, instead, to not do what is most likely premature
optimization.

And anyway, if measurements show you really need to avoid those
"needless" allocations and deallocations, define operator new and
operator delete for the class, and/or use an allocator more suitable
for this particular situation than the built-in one.


The constructor of the class in question has code that exists in no
order member function of the class.

I need to run this code a couple of times a second, but I don't want to
fragment the heap (or have the overhead of allocating memory each time).

Also, when the algorithm's finished, I'd like to be able to deallocate
the memory of the object which already had its destructor invoked.

How would I use operator delete? Something like the following?

::eek:perator delete (p);

(Do you need to write "operator"? Is there any difference between

::new(p) T;

and:

::eek:perator new(p) T;
)
 
A

Alf P. Steinbach

* Tomás Ó hÉilidhe:
Alf P. Steinbach:



The constructor of the class in question has code that exists in no
order member function of the class.

I need to run this code a couple of times a second, but I don't want to
fragment the heap (or have the overhead of allocating memory each time).

Also, when the algorithm's finished, I'd like to be able to deallocate
the memory of the object which already had its destructor invoked.

How would I use operator delete? Something like the following?

::eek:perator delete (p);

(Do you need to write "operator"? Is there any difference between

::new(p) T;

and:

::eek:perator new(p) T;
)

You can't write the latter.

"operator new" is a function, more specifically an allocator function.

"new" on its own is, OTOH., a syntactical construct that except for the
placement form and except for possible allocation failure ends up
calling (1) some "operator new", (2) a constructor, and (3) if the
constructor fails via an exception, the corresponding "operator delete".


Cheers, & hth.,

- Alf
 
A

Andrey Tarasevich

Tomás Ó hÉilidhe said:
...
How would I use operator delete? Something like the following?

::eek:perator delete (p);
...

Yes. However, keep in mind that even if you get rid of the scope
resolution operator ('::'), this is still not 100% equivalent to the
"normal" call to 'operator delete' made from inside of a
delete-expression. Delete-expression supports overloaded class-specific
'operator delete' functions and makes sure that the proper 'operator
delete' is called based the dynamic type of the object. An explicit call
to 'operator delete' does not do that.
 
S

Sean Hunt

"delete" does two things:

1) Invokes the destructor
2) Deallocates the memory

We can manually invoke the destructor with:

p->~T();

But is there any way to manually deallocate the memory without invoking
the destructor? Something like "placement delete" perhaps? I'd be using
it where I'd be continuously constructing and destroying an object:

T *const p = new T;

p->~T();

::new(p) T;

p->~T();

::new(p) T;

p->~T();

::new(p) T;

p->~T();

::new(p) T;

p->~T();

SomeSortOfPlacementDelete(p); /* Just de-allocate, don't destruct */

If you just need deallocate without calling the destructing, the
following is also a (probably sub-optimal) option, but it doesn't use
any explicit calls:

delete [] new char [sizeof(T)];
 
A

acehreli

"delete" does two things:

1) Invokes the destructor
2) Deallocates the memory

We can manually invoke the destructor with:

p->~T();

But is there any way to manually deallocate the memory without invoking
the destructor?

free :)
Something like "placement delete" perhaps? I'd be using
it where I'd be continuously constructing and destroying an object:

T *const p = new T;


p->~T();

::new(p) T; etc.
SomeSortOfPlacementDelete(p); /* Just de-allocate, don't destruct */

free(p);

Ali
 
E

Erik Wikström

Alf P. Steinbach:



The constructor of the class in question has code that exists in no
order member function of the class.

I need to run this code a couple of times a second, but I don't want to
fragment the heap (or have the overhead of allocating memory each time).

Can not help you with your question, but I wonder why you can not use a
loop?

while (some condition)
{
T t;
// do stuff
}

This will create the object on each iteration and run the destructor
when each iteration is done, and it does not have any memory/allocation
overhead.

Of course, another solution would be to not call the destructor the last
time, and instead use delete, but that would mean you have a special
case to handle.
 
J

James Kanze

* Tomás Ó hÉilidhe:
If you know the exact size used for the original allocation
you could perhaps use ::eek:perator delete.

Why would you need to know the size?

What you do need to know is the actual address returned by
the ::eek:perator new function. If there's no inheritance
involved, this is the address of the object, of course, but if
all you've got is a pointer to base, then it might not be the
correct address. (But the only cases I can think of where
calling ::eek:perator delete() directly would make sense is when
you've also called ::eek:perator new() directly. So just save that
address, and use it.)
However I recommend, instead, to not do what is most likely
premature optimization.
And anyway, if measurements show you really need to avoid
those "needless" allocations and deallocations, define
operator new and operator delete for the class, and/or use an
allocator more suitable for this particular situation than the
built-in one.

That's certainly a better solution. And I think boost has a
fixed length allocator, which means you don't even have to
implement that (not that it's very difficult, but using the
Boost code means writing 0 lines of code yourself, and it's very
difficult to do better).
 
A

Alf P. Steinbach

* James Kanze:
Why would you need to know the size?

You wouldn't for the global operator delete.

Not sure what I was thinking, possibly that sentence was the final
result of writing two sentences too fast.

A class-specific operator delete may have two arguments, the pointer and
the size. To call a two-argument version explicitly you must presumably
supply a valid size, in the general case. The global operator delete
requires only the pointer.

For example, as I recall the Loki small object allocator relies on the
size argument, instead of storing that size.

Anyway, above is what my circuits come up with now that you've pointed
out that that sentence was less than meaningful. ;-)


[snip]
That's certainly a better solution. And I think boost has a
fixed length allocator, which means you don't even have to
implement that (not that it's very difficult, but using the
Boost code means writing 0 lines of code yourself, and it's very
difficult to do better).

Will have to look into that -- later...

Cheers,

- Alf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,738
Latest member
JinaMacvit

Latest Threads

Top