Как получить произвольное выравнивание массива в VS2019? - PullRequest
0 голосов
/ 30 мая 2020

Этот код не дает правильного выравнивания:

alignas(4096) int* p = new int[1024];
printf(“%x”, p);

Это должно напечатать

0x......000

с тремя нулями в конце. Я не могу заставить его работать. Возможно ли это вообще?

1 Ответ

1 голос
/ 30 мая 2020

Ваш текущий код выравнивает указатель int* по границе байта 4096. Что вы хотите сделать, так это выровнять память, выделенную new, для выравнивания с границей.

Единственный стандартный способ сделать это - с C ++ 17 или выше, используя либо operator new с аргументом std::aligned_val_t, либо std::aligned_alloc. Например:

int* p = new(std::align_val_t{4096}) int[1024];
...
delete [] p;

// or a more C-style way
int* p = static_cast<int*>(std::aligned_alloc(4096, sizeof(int)*1024));
...
std::free(p);

Вот рабочий пример обозревателя компилятора .


Если вы не используете C ++ 17, вам потребуется используйте специфичные для ОС c функции выделения выравнивания, такие как posix_memalign для POSIX-совместимых операционных систем или _aligned_malloc в Windows.

В качестве альтернативы, если в вашей системе установлены заголовки C11, вы можете использовать C -стандарт aligned_alloc, определенный в <stdlib.h>. Это то же самое, что и эквивалент std::aligned_alloc, за исключением того, что пространство имен с указанием std:: гарантированно будет доступно только с C ++ 17 или выше.


Изменить: Похоже, что MSV C не позволяет первой форме использовать operator new из-за того, что они воспринимают как двусмысленность в стандарте (подробнее см. Раздел комментариев здесь ). Если вы работаете с MSV C или ищете наиболее переносимый код - вам следует использовать вместо него std::aligned_alloc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...