1

I want to define my own placement new and placement delete(taking extra parameters), and I found I could invoke the placement correctly, while I couldn't access the placement delete. Could anyone tell me whether I define the placement delete incorrectly or I invoke it incorrectly?

class A
{
public:
    A( int a ) : a(a){}

    static void* operator new( std::size_t, int ); // the placement new
    static void operator delete( void*, int )throw(); // the corresponding placement delete
private:
    int a;
};

void* A::operator new( std::size_t size, int n )
{
    std::cout << "size: " << size << "  " << "n: " << n << std::endl;
    return ::operator new(size);
}

void A::operator delete( void* p, int n )throw()
{
    std::cout << "n: " << n << std::endl;
    ::operator delete(p);
}

int main( int argc, char* argv[] )
{
    A* a = new(10) A(100);

    std::cout << std::endl;

    delete(4) a; // error???????????????????, but how?

    return 0;
}
Shawn
  • 47,241
  • 3
  • 26
  • 60
JavaBeta
  • 510
  • 7
  • 16
  • possible duplicate of [Why there is no placement delete expression in C++?](http://stackoverflow.com/questions/5857240/why-there-is-no-placement-delete-expression-in-c) – Suma Jul 15 '13 at 14:33
  • This doesn't look like placement new, especially the way you instantiated your `A *` pointer (not sure 10 is a correct memory location :P). Take a look here: http://www.parashift.com/c++-faq/placement-new.html – Xaqq Jul 15 '13 at 14:33
  • 1
    @Xaqq: It is *a* form of placement new, but not the most common one which passes in the address where the object will be placed. – Ben Voigt Jul 15 '13 at 14:35
  • I'd prefer leaving `new` and `delete` alone and rather define proper constructors/destructors - even if it worked, which it does not, it's very confusing if `A * a = new A` behaves completely differently from `A a` – nikolas Jul 15 '13 at 14:38
  • In your constructor for class A, the parameter to the constructor, a is the same name as the member variable: a. Don't ever fall into that trap of naming the parameters the same as a member variable. If you lie to your compiler it may just believe you. – C.J. Jul 15 '13 at 14:58

1 Answers1

5

Placement delete is available only to handle exceptions which occur during evaluation of a placement new expression. If construction finishes successfully, then later on normal delete will be used.

You can call a placement deallocation function explicitly, but it won't have the same behavior as the delete operator (it won't call the destructor automatically).

In your case, the corresponding code would be:

a->~A();
A::operator delete(a, 4);

Yuck!

For arrays it is even worse, because you can't retrieve the number of elements (and number of destructors to call) from the location where the compiler stored that for its own use.

Design your overloaded operator new so that it pairs correctly with one-argument operator delete. Then users of your class can use delete ptr; and std::unique_ptr etc.

If you do require custom deallocation, then an allocation wrapper which returns std::shared_ptr with a custom deleter will be better than custom placement new.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Is that means I can't change the signature of placement delete and I can only redefine it? And when I want to release the resource, I call: a->~A(); delete a; ? – JavaBeta Jul 15 '13 at 14:40
  • 1
    @JavaBeta: No. `delete a;` would call the destructor a second time, and then the one-argument deallocation function `operator delete(void*)`. If you want to call a different (placement) deallocation function, do so explicitly like my answer shows. If you can make the ordinary deallocation function work right, then the user of your class can say just `delete p;` and get both the destructor call and deallocation at once. – Ben Voigt Jul 15 '13 at 14:42
  • Oh, I have to call it explicitly through the scope operator? It works, it still confuses me, anyway the placement new and placement delete invoking mechanism is quite inconsistent. – JavaBeta Jul 15 '13 at 14:43
  • 1
    @JavaBeta: It's because you're not intended to use placement delete. It's there, and you can use it, but for technical reasons (see http://stackoverflow.com/a/14119344/103167 also linked in comments to this question) it's not seamless. – Ben Voigt Jul 15 '13 at 14:45
  • Yeah, I think I confuse operator delete and delete expression again. Thank for your@Ben Voigt instant and helpful comments! – JavaBeta Jul 15 '13 at 14:48