C++: выделите блок T, не вызывая конструктора

Я не хочу вызванного конструктора. Я использую новое размещение.

Я просто хочу выделить блок T.

Мой стандартный подход:

T* data = malloc(sizeof(T) * num);

однако, я не знаю, является ли (data+i) T-aligned. Кроме того, я не знаю, является ли это правильный "C++" путь.

Как я должен выделить блок T, не вызывая его конструктора?

25
задан Michael Anderson 4 March 2010 в 22:34
поделиться

3 ответа

Во-первых, вы не выделяете «блок из T * ». Вы выделяете «блок из T ».

Во-вторых, если ваш T имеет нетривиальный конструктор, то до тех пор, пока элементы не будут созданы, ваш блок на самом деле не является «блоком T», а скорее блоком необработанной памяти. Привлечь сюда T вообще нет смысла (кроме вычисления размера). Указатель void * больше подходит для необработанной памяти.

Чтобы выделить память, вы можете использовать все, что захотите

void *raw_data = malloc(num * sizeof(T));

,

void *raw_data = new unsigned char[num * sizeof(T)];

,

void *raw_data = ::operator new(num * sizeof(T));

или

std::allocator<T> a;
void *raw_data = a.allocate(num);
// or
// T *raw_data = a.allocate(num);

. Позже, когда вы фактически создадите элементы (используя новое размещение, как вы сказали), вы, наконец, получить значимый указатель типа T * , но пока память необработанная, использование T * не имеет большого смысла (хотя это и не является ошибкой).

Если ваш T не имеет некоторых экзотических требований к выравниванию, память, возвращаемая вышеуказанными функциями распределения, будет правильно выровнена.

Возможно, вам действительно захочется взглянуть на утилиты памяти, предоставляемые стандартной библиотекой C ++: std :: allocator <> с методами allocate и construct , а также алгоритмы типа uninitialized_fill и т. д. или попытки изобретать велосипед.

25
ответ дан 28 November 2019 в 21:37
поделиться

T* data = reinterpret_cast(operator new(sizeof(T) * num));

Или просто используйте std::vector и не беспокойтесь об этих низкоуровневых деталях памяти ;)

1
ответ дан 28 November 2019 в 21:37
поделиться

Возврат из malloc выровнен для любого типа, так что это не проблема.

Обычно в C ++ предпочтительнее использовать :: operator new . Вы также можете рассмотреть возможность использования Allocator , который дает некоторую дополнительную гибкость (например, возможность легко переключать распределители.

6
ответ дан 28 November 2019 в 21:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: