Работает ли спецификатор alignas с 'new'?

Мой вопрос довольно прост;

Работает ли спецификатор alignas с 'new'? То есть, если структура определена для выравнивания, будет ли она выравниваться при выделении с новым?

9 голосов | спросил Skeen 20 MaramWed, 20 Mar 2013 02:41:17 +04002013-03-20T02:41:17+04:0002 2013, 02:41:17

2 ответа


0

Если выравнивание вашего типа не выровнено, то да, будет работать new по умолчанию. «Выровненный» означает, что выравнивание, указанное в alignas, больше, чем alignof(std::max_align_t). new по умолчанию будет работать с неподписанными типами более или менее случайно; Распределитель памяти по умолчанию всегда выделяет память с выравниванием, равным alignof(std::max_align_t).

Если выравнивание вашего типа слишком выровнено, вам не повезло. Ни new по умолчанию, ни глобальный new Оператор, который вы напишете, сможет даже узнать требуемое выравнивание типа, не говоря уже о выделении памяти, соответствующей ему. Единственный способ помочь в этом случае - перегрузить класс operator new, который сможет запросить выравнивание класса с помощью alignof

Конечно, это не будет полезно, если этот класс используется в качестве члена другого класса. Только если этот другой класс также не перегружает operator new. Так что простое new pair<over_aligned, int>() не будет работать.

Предложение для C ++ 17 (которое было принято) добавляет поддержка динамического выделения выровненных типов , с перегрузками operator new/delete, которые принимают ---- +: = 12 =: + ---- назначаемого типа. Это также будет поддерживать выравнивания меньше, чем максимально выровненный тип, поэтому ваш распределитель памяти не всегда должен возвращать память, выровненную по alignof.

Тем не менее, компиляторам не требуется для поддержки переопределенных типов вообще.

ответил Nicol Bolas 20 MaramWed, 20 Mar 2013 03:03:57 +04002013-03-20T03:03:57+04:0003 2013, 03:03:57
0

Нет, это не так. Структура будет дополнена запрошенным выравниванием, но она не будет выровнена. Однако есть вероятность, что это будет разрешено в C ++ 17 (тот факт, что это предложение C ++ 17 существует, должно быть довольно хорошим доказательством того, что это не может работать в C ++ 11).

Я видел, как это работает с некоторыми распределителями памяти, но это была чистая удача. Например, некоторые распределители памяти будут выравнивать свои выделения памяти в степени 2 запрошенного размера (до 4 КБ) в качестве оптимизации для распределителя (уменьшить фрагментацию памяти, возможно, упростить повторное использование ранее освобожденной памяти и т. Д.) , Однако новые реализации /malloc, которые включены в протестированные мною системы OS X 10.7 и CentOS 6, не делают этого и дают следующий код:

#include <stdlib.h>
#include <assert.h>

struct alignas(8)   test_struct_8   { char data; };
struct alignas(16)  test_struct_16  { char data; };
struct alignas(32)  test_struct_32  { char data; };
struct alignas(64)  test_struct_64  { char data; };
struct alignas(128) test_struct_128 { char data; };
struct alignas(256) test_struct_256 { char data; };
struct alignas(512) test_struct_512 { char data; };

int main() {
   test_struct_8   *heap_8   = new test_struct_8;
   test_struct_16  *heap_16  = new test_struct_16;
   test_struct_32  *heap_32  = new test_struct_32;
   test_struct_64  *heap_64  = new test_struct_64;
   test_struct_128 *heap_128 = new test_struct_128;
   test_struct_256 *heap_256 = new test_struct_256;
   test_struct_512 *heap_512 = new test_struct_512;

#define IS_ALIGNED(addr,size)   ((((size_t)(addr)) % (size)) == 0)

   assert(IS_ALIGNED(heap_8, 8));
   assert(IS_ALIGNED(heap_16, 16));
   assert(IS_ALIGNED(heap_32, 32));
   assert(IS_ALIGNED(heap_64, 64));
   assert(IS_ALIGNED(heap_128, 128));
   assert(IS_ALIGNED(heap_256, 256));
   assert(IS_ALIGNED(heap_512, 512));

   delete heap_8;
   delete heap_16;
   delete heap_32;
   delete heap_64;
   delete heap_128;
   delete heap_256;
   delete heap_512;

return 0;
}
ответил Thiago 14 Mayam15 2015, 02:34:19

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132