4
class Foo{
//some member
    public:
    int bar;
}

int main(){
    char* buffer = new char[100];
    Foo* f = new(buffer)Foo();
//do i have to
    delete f;
//or is 
    delete[] buffer;
//enough
}

Sure i have to delete it if the delete of Foo has some major effect on the system but lets say it is a simple storage object which i place which is compleatly inside of the buffer and has no deconstructor which does delete some other things.

  • Do i have to delete a object which where places with the new inside of a buffer or is it enough to delete the buffer?
  • If i have to call delete on every object inside of the buffer, why do i have todo this?

I read: what-uses-are-there-for-placement-new and he also says

You should not deallocate every object that is using the memory buffer. Instead you should delete[] only the original buffer.

Shawn
  • 47,241
  • 3
  • 26
  • 60
bemeyer
  • 6,154
  • 4
  • 36
  • 86

1 Answers1

9

The correct way to destroy that object is with an explicit destructor call:

f-> ~Foo();

Usually placement new is used with memory on the stack. In this case, it's heap allocation, so you do need to free the buffer using the form of delete that matches the new.

delete[] buffer;
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • So if i use placement i need to call the destructor explicit. But the question is why i need todo this and does it even matter if its stack or heap? Well sure if its heap i need to call delete, but does it matter to the `~Foo()` call i need todo? – bemeyer Jul 27 '15 at 11:29
  • @BennX: `f->~Foo()` seems no-op in your case, but if you have `std::string` in `Foo` for example, it is no longer true and you will have leak. – Jarod42 Jul 27 '15 at 11:32
  • 2
    @BennX Placement new separates allocation from initialization. Essentially, since you created the object using two steps, destroying it requires the opposite two steps. `delete f` might work in practice, because the pointer values happen to match up, but it's undefined behavior: not guaranteed to work. Better to be tidy and correct than terse. – Potatoswatter Jul 27 '15 at 11:33
  • @Jarod42 I got it. Sure i need to call the delete in this case. But if i only have simple types? (In the case where i want to use it it only contains simple types) – bemeyer Jul 27 '15 at 11:35
  • In that case, the `~Foo()` is a no op, and the compiler will optimize it away. – fredoverflow Jul 27 '15 at 11:36
  • @Potatowatter thanks for this short and simple explenation. But does it matter if the class only has simpletypes? Doesnt they are at the spot where i created it and should be deleted with the buffer delet? – bemeyer Jul 27 '15 at 11:36
  • @BennX If the type is trivially destructible, it doesn't matter whether you call the destructor or not — by definition. Even for `std::string`, you're not actually required to call the destructor, to obtain a correct program. C++ does permit you to leak the memory. – Potatoswatter Jul 27 '15 at 11:37
  • @Potatoswatter So i am right, that if it only contains types which are "really" inside the buffer, it doesnt matter and i dont need to call the destructore explicit only delete the buffer? (so no dynamic structures) In the end it is really important that i dont have a memory leak.. – bemeyer Jul 27 '15 at 11:39
  • @BennX It doesn't matter, but it also doesn't cost anything to write the destructor call, for the sake of caution. – Potatoswatter Jul 27 '15 at 11:40
  • @Potatoswatter True it doesnt matter if i always have the handle, but if i only got a weaktype and cast a position to the type it does matter if i have to traverse stepwise over the buffer to check if there is a valid object and if i need to delete it. Thanks alot for the help. – bemeyer Jul 27 '15 at 11:41