2

I have some code:

MemoryManager mm;
char *a = new (mm) char [len +1];

How can I free all the memory by pointer a?

Praetorian
  • 106,671
  • 19
  • 240
  • 328
user3818229
  • 1,537
  • 2
  • 21
  • 46

1 Answers1

3

Firstly, there's no way that anything builtin can know how to delete your a data - you're the one that allocated it with placement new, so it's your job to clean it up.

Unfortunatly, there doesn't appear to be a way of overloading delete for this. Just use a method name of your choice:

MemoryManager mm;
char *a = new (mm) char [len +1];

mm.cleanup(a); // since mm allocated us the memory, only it knows how to destroy it.
               // Note that this also needs to do obj.~ClassName() for class types

See 'is there a placement delete' in the isocpp faq.

Eric
  • 95,302
  • 53
  • 242
  • 374
  • Can somebody explain this example in more details? – gomons Apr 21 '15 at 21:12
  • @gomons: They're creating a `char[]` using a custom memory manager. They want to tell this memory manager to clean up the memory. – Eric Apr 21 '15 at 21:13
  • So `char *a = new (mm) char [len +1];` calls `operator new()` overloaded in `MemoryManager`? – gomons Apr 21 '15 at 21:14
  • I think it calls `operator new[](sizeof(char[len+1]), mm)` – Eric Apr 21 '15 at 21:17
  • and you are right, so I can't understand the sense of MemoryManager class. – gomons Apr 21 '15 at 21:21
  • In result, I've concluded the answer is: `operator delete (a, mm);` (to call delete like as the usual method) – user3818229 Apr 22 '15 at 04:49
  • @user3818229 You'll want to define that anyhow (in case that the construction throws). But wait -- what happens if the type has a virtual destructor? Is the proper `delete` called? ... so that doesn't work. `operator delete(a,mm)` *should not call the destructor of `a`*. Partly because if the constructor of `a` throws, it will be automatically called with a destroyed `a`. – Yakk - Adam Nevraumont Apr 23 '15 at 14:44
  • In short, `operator delete(a,mm)` can only be called after `a.~A()` is called. It may not call `a.~A()` or it will lead to UB if you use custom placement-new on any type with a throwing constructor. You could call `operator delete(a, mm, please_destroy_as_well{})` (ie, pass a tag type), but that seems rude. – Yakk - Adam Nevraumont Apr 23 '15 at 14:50