2011-11-16 2 views
5

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

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

+0

Это не имеет никакого отношения к шаблонам или C++ 11 – Dani

ответ

8

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

#include <new> 

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

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

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

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

+0

Удивительный! Я знал, что должен быть простой способ сделать это. Спасибо – wallacer

4

Во-первых, просто зная, что 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; 
} 
+1

+1 за упоминание требования к выравниванию. –

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