Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

operator new already has a body

I am trying to implement operator new with parameter as global. There is no problem if new without args is overloaded, but I get followings errors when trying to compile

inline void* operator new(size_t, void* p) {
    //...
    return p;
}

c:\bjarne_exercise_6.cpp(14): error C2084: function 'void *operator new(size_t,void *) throw()' already has a body c:\program files\microsoft visual studio 10.0\vc\include\new(55) : see previous definition of 'new'

c:\bjarne_exercise_6.cpp(40): error C2264: 'operator new' : error in function definition or declaration; function not called

I have just solved this, you have to declare this before you #include stdafx.h No, not true. It compile well but still not this function is called but the version from new header file. It is so, because placement new(with 2 params) is already defined in new header. The ordinary new (with just 1, size_t parameter) is only declared there, so you can still overload it. So if you want special new with more than 1 parameter the solution suggested by @trion below is appropriate.

like image 409
4pie0 Avatar asked Dec 16 '22 20:12

4pie0


2 Answers

This placement form of operator new (as the Standard calls it) is already defined in a C++ program in the global namespace, you cannot provide a definition there yourself. Unlike other global operator news, this one is not replaceable.

like image 167
Luc Danton Avatar answered Dec 27 '22 09:12

Luc Danton


The C++ standard defines a placement operator new taking an additional void* in the header file <new>. Its implementation is similar to this:

void* operator new(size_t, void* m)
{
    return m;
}

It's commonly used to instantiate objects on already allocated memory, e.g. by STL containers which separate allocation from instantiation. So if you include any standard header depending on <new>, the placement new will already be defined.

If you want to create your own version of operator new with different semantics, you can use a dummy parameter to disambiguate the situation:

struct my_new_dummy {} dummy;
void* operator new(size_t, my_new_dummy, void* m);

//...

int mem;
int* ptr = new(dummy, &mem) int;

Edit: The reason why you can redefine the ordinary operator new but not placement new, is that the former is by default defined by the compiler and can be overridden manually, whereas placement new is defined in a header, therefore causing a conflict with your re-definition.

like image 43
Fabian Knorr Avatar answered Dec 27 '22 10:12

Fabian Knorr