2015-05-22 4 views
1

Скажем, у меня есть этот код:Можно ли повторно использовать выделение удаленных адресов?

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] после вызова delete?

То, что я имею в виду при повторном использовании, заключается в том, чтобы использовать это адресное пространство снова как выделенный адрес.

Я имею в виду, используя этот код

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

При повторном использовании вы имеете в виду перераспределение памяти и ее использование? –

+0

Повторно использовать его каким образом? Повторное использование пространства хранения для хранения другого указателя? Конечно. Сделайте что-нибудь с адресом внутри 'buffers [1]' после того, как вы его удалили? Неа. – user657267

+0

Да как использовать это пространство снова для другого экземпляра объектов –

ответ

2

Прежде всего: placement new ожидает указатель, а не указатель на указатель

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

что сказал, после того, как вы удалили память, на который указывает buffers[1] вам нужно выделить новую память перед использованием чтобы сохранить другой экземпляр объекта.

Это цель new[] и delete[] в первую очередь: маркировка куска памяти как «более не нужна» или «используется».

Вы можете, однако, конечно, повторно использовать указатель buffers[1], чтобы указать на новое место памяти, но делать это после того, как код, который вы публикуемым является недействительным:

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

, поскольку вы пытаетесь построить объект на удаленной памяти. Это вызовет неопределенное поведение.

Это справедливо вместо

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 
+0

Я отредактировал мой пост, вы можете проверить его? –

+0

Я вижу, спасибо. –

+0

Вопрос: почему я получаю какие-то странные символы, когда я делаю 'cout << буферы [1] << endl;'? Я использовал ваш код –

0

Если вы хотите повторно использовать буфер для другого экземпляра объекта, который Вы должны использовать размещение нового для инициализации объектов на этой выделенной памяти.

char buffer[<size>]; 
MyClass *p = new (buffer) MyClass; 
p->~MyClass(); 
p = new (buffer) MyClass; 
+0

Тем не менее, я использую новое размещение на своем коде. –

+0

Но вы удаляете базовый буфер –

+0

Я отредактировал мое сообщение, не могли бы вы проверить его? –

0

Если за счет повторного использования вы имеете в виду, чтобы присвоить указатель objects[1] к выделенной памяти, то да, вы можете использовать его.

Если вы хотите спросить, можете ли вы использовать память, указанную указателем и которую вы просто освободили с помощью delete[], тогда вы не сможете ее повторно использовать. Вы можете использовать только выделенную память.

1

Буферы представляют собой множество указателей. Вы можете использовать буферы [1] для хранения нового указателя. Но вы не должны разыменовывать буферы [1], пока не поместите новый действительный указатель внутри.

У меня такое ощущение, что вы хотите переместить пространство, выделенное в буферах, но сохранить внутри себя внутри. Вы можете сделать это до тех пор, пока вы не удалите из памяти вы наделив 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]; 

Однако вы не можете хранить объекты различного типа, в том же месте, так как их размер, вероятно, не совпадают. В этом случае вы должны освободить выделенную память (используя delete []), а затем перераспределите ее с помощью нового.

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]; 
+0

Хмм интересный ответ. плохо помните об этом. Таким образом, это означает, что я могу повторно использовать адрес так, как я его не освобожу? –

+0

Нет, неверный код: объекты - это указатель на объекты Obj, а не объекты A. –

+0

@ CarloBrew Хорошо посмотрите на это так. Вы выделили sizeof (Obj) байты памяти и сохранили указатель на него в буферах [1]. Пока вы не освобождаете эту память, вы можете использовать ее для чего угодно. Однако ваше новое редактирование показывает, что вы хотите сохранить там другой объект (объект A). sizeof (A), вероятно, отличается от sizeof (Obj), поэтому вам может потребоваться освободить память и выделить новый фрагмент с размером объекта A. – rozina

Смежные вопросы