Создать объект в памяти, на который указывает указатель void - PullRequest
5 голосов
/ 16 ноября 2011

Если у меня есть пустота * для некоторого куска свободной памяти, и я знаю, что по крайней мере доступен размер size (T), есть ли способ создать объект типа T в этом месте в памяти?

Я только собирался создать объект T в стеке и переписать его, но кажется, что должен быть более элегантный способ сделать это?

Ответы [ 2 ]

8 голосов
/ 16 ноября 2011

Используйте новое размещение для него:

#include <new>

void *space;
new(space) T();

Не забудьте удалить его, прежде чем освободить память:

((T*)space)->~T();

Не создавайте объект в стеке и не запоминайте его, его нетбезопасно, что если объект имеет свой адрес, хранящийся в элементе или элементе элемента?

4 голосов
/ 16 ноября 2011

Во-первых, просто зная, что sizeof(T) доступного объема памяти недостаточно.Кроме того, вы должны знать, что указатель void правильно выровнен для типа объекта, который вы хотите выделить.Использование неправильно выровненных указателей может привести к снижению производительности или к зависанию приложения, в зависимости от вашей платформы.

Однако, если вы знаете, что свободная память и выравнивание правильны, вы можете использовать новое размещение для создания там своего объекта.Однако имейте в виду, что вы также должны явно уничтожить его в этом случае.Например:

#include <new>      // for placement new
#include <stdlib.h> // in this example code, the memory will be allocated with malloc
#include <string>   // we will allocate a std::string there
#include <iostream> // we will output it

int main()
{
  // get memory to allocate in
  void* memory_for_string = malloc(sizeof(string)); // malloc guarantees alignment
  if (memory_for_string == 0)
    return EXIT_FAILURE;

  // construct a std::string in that memory
  std::string* mystring = new(memory_for_string) std::string("Hello");

  // use that string
  *mystring += " world";
  std::cout << *mystring << std::endl;

  // destroy the string
  mystring->~string();

  // free the memory
  free(memory_for_string);

  return EXIT_SUCCESS;
}
...