Я строю распределитель памяти и использую размещение новых.
Скажем, я хочу «поместить» 10 элементов в уже выделенный массив в куче.
Сначала обычный new выделяет необходимое количество байтов в куче, затем я создаю свои WE
объекты в соответствующих местах.
struct WE {
WE() {
std::cout << "WE default constructed\n";
}
~WE() {
std::cout << "WE default destructed\n";
}
double d;
int i;
char c;
};
Правильно ли следующее использование размещения?
Код компилируется и вывод кажется правильным, но у меня есть некоторые сомнения.
// 1. allocate
const int elements = 10;
int nbytes = elements * sizeof(WE);
char* memory = new char[nbytes];
WE* pB = (WE*)memory;
int step = sizeof(WE);
// 2. construct
for (int i = 0; i < nbytes; i += step)
new (pB + i) WE();
// 3. process
for (int i = 0; i < nbytes; i += step)
pB[i].i = i * 2;
for (int i = 0; i < nbytes; i += step)
std::cout << '[' << i << ']' << '=' << pB[i].i << '\n';
// 4. destruct
for (int i = 0; i < nbytes; i += step)
pB[i].~WE();
// 5. deallocate
delete[] memory;
pB = nullptr;
memory = nullptr;
Если все хорошо с вопросом выше, то позвольте мне задать дополнительный вопрос, как бы я выровнял этот массив по произвольной границе байта?
Скажем, я хочу выравнивание на sizeof(WE)
, что 16
(а не на alignof(WE)
, что 8
). Будет ли этой модификации: alignas(sizeof(WE)) char* memory = new char[nbytes];
достаточно, чтобы сделать трюк? Я также слышал о std::aligned_storage
. Я не уверен, может ли это дать какие-либо преимущества. (Если второй вопрос вас смутил или я что-то напутал в первой части, забудьте об этом.) Заранее спасибо.