views:

122

answers:

6

C++ allows overloading operator new - both global and per-class - usual operator new, operator new[] used with new[] statement and placement operator new separately.

The former two of those three are usually overloaded for using customized allocators and adding tracing. But placement operator new seems pretty straightforward - it actually does nothing inside. For example, in Visual C++ the default implementation just returns the address passed into the call:

//from new.h
inline void* operator new( size_t, void* where )
{
   return where;
}

What else could it do? Why and how could I sensibly overload placement operator new?

A: 

One example is at Stroustrup's FAQ.

dirkgently
Honestly I don't get that example.
sharptooth
+2  A: 

Technically, a placement operator new is any operator new that takes additional arguments besides the size of the memory needed.

So, new(std::nothrow) X uses a placement operator new and so does new(__FILE__, __LINE__) X.

The only reason for overriding the operator new(size_t, void*) could be to add tracing information, but I think the need for that will be pretty low.

Bart van Ingen Schenau
One reason for implementing it might be to force the use of a particular memory allocator; this has come up for us when doing complex things on Windows where it was necessary to force the use of the allocator used by one particular DLL rather than another one. (Yes, different libraries were using different allocators. It all worked, as long as code matched `new` from one lib with `delete` from the same lib.)
Donal Fellows
The first sentence is wrong, placement new has a specific meaning. And placement new cannot be overloaded or replaced.
GMan
@GMan: You are right. There seems to be no specific name for `operator new` overloads that take additional parameters, although they are usually invoked using the placement syntax.
Bart van Ingen Schenau
A: 

My primary usage is to create a large array of objects. Its performing much better and has less overhead to allocate the memory in a whole block, i.e. using VirtualAlloc from Win32 (when programming windows). Then you just pass a ptr within that block to each objects placement new such as:

char *cp = new char[totalSize];

for(i = 0; i < count; i++, cp += ObjSize)        
{                                                        
    myClass *obj = new(cp) myClass;             
}
RED SOFT ADAIR
That's using, not overloading...
Matthieu M.
IIUC, he is not asking for usage cases of the placement new operator itself, but for usage cases of *overloading* it.
Matteo Italia
+1  A: 

The most obvious override would be to copy this implementation.

Another sensible one would be to add some checks (for example, verifying that there is no "bound-marker" within the request zone).

I think however that the point is more than you HAVE to override it, as soon as you override the others (for a given class), because of the mechanics of name look up (or not overriding it to prevent its use, that's fine too, but it's a conscious decision).

Matthieu M.
A: 

I've seen an example where two-argument new [] was overwritten to return memory blocks pre-filled with the char passed as the additional argument. I don't remember what the original code used (probably memset()), but it was functionally something like this:

#include <iostream>
#include <algorithm>
#include <new>
void* operator new [](size_t n, char c)
{
        char* p = new char[n];
        std::fill(p, p+n, c);
        return p;
}
int main()
{
        char* p = new('a') char[10];
        std::cout << p[0] << p[1] << ".." << p[9] << '\n';
}

although I guess this wouldn't be called "placement" new because it does not perform placement. It could probably be useful if templated so that it can build arrays of any type, filled with a copy of the object passed as its second argument... but then, we have containers for that anyway.

Cubbi
+2  A: 

The correct answer is you cannot replace operator placement new.

§18.4.​1.3 Placement forms
These functions are reserved, a C++ program may not define functions that displace the versions in the Standard C++ library.

The rationale: The only purpose of the allocation and deallocation operators is to allocate and deallocate memory, so when given memory nothing more should be done. (The standard specifically notes that these functions "Intentionally perform no other action.")

GMan
Wow. Visual C++ 9 happily allows that.
sharptooth
@sharptooth: What's your test program? Not surprising, it's illegal in the same way it's illegal to add things (in general) to the `std` namespace. The language itself is none the wiser, but the standard library forbids it.
GMan