tags:

views:

159

answers:

4

Is there a difference between:

operator delete(some_pointer);

and

delete some_pointer;

and if so what is the difference and where one should use one and where the other version of this operator? Thanks.

+1  A: 

delete some_pointer; is the "correct" one to use.

operator delete(some_Pointer); exist mainly as an artifact of the syntax for defining you own delete operator. That is, because you define an plus operator as;

 myclass::operator+(myclass b) {....}

you really could write:

 myclass c = a.operator+(b);

but no one ever does that. They use:

 myclass c = a + b;

Similarly, you could write operator delete(some_Pointer);, but no one ever does.

James Curran
They are actually not the same thing...
Dima
@Dima: At what point in my answer did I say they were the same thing?? I just said to use "Delete some_Pointer" and that you could, but no one does, use the other form.
James Curran
@James: Your answer seems unclear about that ...
Cedric H.
@James they say that they are not in the same relationship that "operator+" and "+" is. "new" will not just call "operator new" and be happy. It does something in addition. You cannot even do `some_pointer->~T(); operator delete(some_pointer)` : It will still be different, because among other things there might be class-specific operator delete functions but the manual just calls the one in scope, and if the class has a virtual destructor, the Standard requires the "operator delete" of the dynamic type of the object to be used but a manual call cannot accomplish that at all.
Johannes Schaub - litb
+4  A: 

operator delete() simply frees the memory. delete some_pointer calls some_pointer's destructor, and then calls operator delete().

Oli Charlesworth
+12  A: 

Ironically, the delete operator and operator delete() are not the same thing.

delete some_pointer; calls some_pointer's destructor, and then calls operator delete() to free the memory.

You do not normally call operator delete() directly, because if you do the object's destructor will not be called, and you are likely to end up with memory leaks.

The only time you have to care about operator delete() is when you want to do your own memory management by overriding operator new() and operator delete().

To top it off, you should also be aware that delete and delete [] are two different things.

Dima
That's exactly what I was looking for. Thanks.
There is nothing we can do
+1  A: 

At least in my experience, it's more common to implement operator new and operator delete than to actually use (i.e., call) them, at least directly.

Usually, you use operator new and operator delete indirectly -- you write a new expression, like A *a = new A;. To implement this, the compiler generates code that invokes operator new to allocate raw memory, then invokes a A::A to convert that raw memory into an A object, much as if you'd written:

void *temp = operator new(sizeof A);  // allocate raw memory with operator new
A *a = new(temp) A;                   // convert raw memory to object with placement new

When you're done with the object, you use delete A;. To implement that, the compiler invokes the dtor for the object, and then frees the memory, roughly like you'd done:

a->~A();
operator delete(a);

There are also operator [] new and operator [] delete, which are used when/if you allocate/delete arrays -- but there isn't necessarily any real difference between the normal version and the array version -- they both just allocate a specified amount of raw memory (though you might guess that the array versions will allocate relatively large amounts of memory, and do some optimization on that basis).

In any case, if you want to optimize how memory is allocated for objects of a particular class you overload these to do it. There are a fair number of existing implementations that you can drop-in and use, especially for situations where you expect to allocate a large number of tiny objects so you need to minimize the overhead associated with each allocation (e.g., HeapLayers, Loki's small block allocator).

One interesting little tidbit: operator new, operator [] new, operator delete and operator [] deleteare alwaysstaticclass members, even if you don't explicitly includestatic` in their declaration/definition.

There are also global versions of all four (::operator new, ::operator [] new, ::operator delete and ::operator [] delete). These mark the "border" between the "internal" C++ memory management, and the outside world. Typically they allocate relatively large chunks of memory from the operating system, and then return smaller pieces to the rest of the program upon request. If you want to (try to) optimize memory management for your entire program, you typically do it by overloading (or, really, replacing) these. Again, the typical reason would be if you expect to allocate a lot of small objects (but not in just a few classes). One example of this is the Boost Pool library.

Direct use of any of the above is generally restricted to situations where you need a block of raw memory, not objects. One example would be implementing your own container classes. For example, std::vector normally uses ::operator new (via an Allocator object) to allocate memory in which to store objects. Since it needs to be able to allocate storage, but only later (or perhaps never) create objects in that storage, it can't just use something like data = new T[size]; -- it has to allocate raw memory, then use placement new to create objects in the memory as you add them to the collection (e.g., when you push_back an object). The same is true with std::deque. If you wanted (for example) to implement your own circular buffer "from the ground up", handling all the memory management directly instead of using something like vector for storage, you'd probably need/want to do the same.

Jerry Coffin
@Jerry thanks great answer
There is nothing we can do