1

Let's say I have this code:

Obj*  objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(&buffers[1]) Obj();
// ...
objects[1]->~Obj();
delete[] buffers[1];

Would it be alright to reuse buffers[1] after calling delete?

What I mean by reuse is to use that address space again as the allocated address.

I mean by using this code

objects[2] = new(&buffers[1]) A();
Marco A.
  • 43,032
  • 26
  • 132
  • 246
Carlos Miguel Colanta
  • 2,685
  • 3
  • 31
  • 49

4 Answers4

2

First of all: placement new expects a pointer, not a pointer to a pointer

objects[1] = new(&buffers[1]) Obj(); // Nope
objects[1] = new(buffers[1]) Obj();  // Yes

That said, after you've deleted the memory pointed by buffers[1] you need to allocate new memory before using it to store another instance of an object.

That is the purpose of new[] and delete[] in the first place: marking a chunk of memory as "no longer needed" or "in use".

You can however of course reuse the pointer buffers[1] to point to a new memory location but doing this after the code you posted is invalid:

objects[2] = new(buffers[1]) A();

since you're trying to build an object on a deleted memory location. That is going to trigger undefined behavior.

This is valid instead

Obj*  objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(buffers[1]) Obj();
// ...
objects[1]->~Obj();
delete[] buffers[1];

// Allocate something else and build an object there. Remember that
// 'objects' is an array of pointers to Obj objects
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(buffers[1]) Obj();
// You might now destroy and deallocate
Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • Question, why do i get some weird characters when i do `cout< – Carlos Miguel Colanta May 22 '15 at 08:09
  • 1
    @CarloBrew This will answer your question: http://stackoverflow.com/questions/17813423/cout-with-char-argument-prints-string-not-pointer-value Dont forget buffers[1] is of type char*. – rozina May 22 '15 at 08:11
  • @rozina i see thank you @Marco A. i am curious about the `delete[] buffers[1];` on your code, isn't it marked as "no longer needed" then you used `buffers[1] = new char[sizeof(Obj)];` ? or the delete refers to the address it is being pointed to? – Carlos Miguel Colanta May 22 '15 at 08:21
  • 1
    @CarloBrew the memory that is 'no longer needed' is the one where `buffers[1]` points. Do not confuse that memory area with the pointer itself. – Marco A. May 22 '15 at 08:27
  • @CarloBrew Good. Don't forget to mark this as the accepted answer if it solved your problem. – Marco A. May 22 '15 at 09:18
1

Buffers is an array of pointers. You can use buffers[1] to store a new pointer in it. But you should not dereference buffers[1] until you put a new valid pointer inside.

I have a feeling you want to resue the space allocated in buffers but to store a nother Obj inside. You can do that as long as you don't delete the memory you allocated with buffers[1] = new char[sizeof(Obj)];

Obj*  objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(buffers[1]) Obj();
// ...
objects[1]->~Obj();

// you can store a new Obj object in the same place before deleing memory
objects[2] = new(buffers[1]) Obj();
objects[2]->~Obj();
delete[] buffers[1];

However you cannot store objects of different type in the same location, since their size probably do not match. In that case you have to free the allocated memory (using delete[]) and then reallocate it with new.

Obj*  objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(buffers[1]) Obj();
// ...
objects[1]->~Obj();    
delete[] buffers[1];

buffers[1] = new char[sizeof(A)];
A* objA = new(buffers[1]) A(); // can't store A in objects[] since its not Obj
objA->~A();
delete[] buffers[1];
rozina
  • 4,120
  • 27
  • 49
  • Hmm interesting answer. ill keep that in mind. So it means that i can reuse the address aslong as i dont free it? – Carlos Miguel Colanta May 22 '15 at 07:35
  • Nope, invalid code: objects is a pointer to Obj objects, not A objects. – Marco A. May 22 '15 at 07:38
  • @CarloBrew Well look at it this way. You allocated sizeof(Obj) bytes of memory and stored a pointer to it in buffers[1]. As long as you don't free that memory you can use it for whatever you want. However your new edit shows that you want to store a different object there (object A). sizeof(A) is probably different of sizeof(Obj) so you might have to free the memory and allocate a new chunk with the size of object A. – rozina May 22 '15 at 07:38
0

If you want to reuse a buffer for different instance of an object you should use placement new to initialize the objects on this preallocated memory.

char buffer[<size>];
MyClass *p = new (buffer) MyClass;
p->~MyClass();
p = new (buffer) MyClass;
bazz-dee
  • 687
  • 5
  • 23
0

If by reuse you mean to assign the pointer objects[1] to allocated memory, then yes, you can reuse it.

If you mean to ask, can you use the memory that was pointed by the pointer and which you just deallocated with delete[], then no you can't reuse it. You can only use memory that is allocated.

eerorika
  • 232,697
  • 12
  • 197
  • 326