2016-12-08 3 views
4

Я смотрю на объяснение выровненных-Alloc():. http://en.cppreference.com/w/c/memory/aligned_allocтребования функции aligned_alloc

void *aligned_alloc(size_t alignment, size_t size); 

«Выделяют размер байт неинициализированного хранения которого выравнивание задается выравнивание Параметр размера должен быть составной кратное выравниванию ".

Однако пример кода использует его как это:

int *p2 = aligned_alloc(1024, 10*sizeof *p2); 

10 * SizeOf * р = 40, так что это не кратен 1024.

Что я неправильно?

+1

Я думаю, что опечатка: возможно, она также имела значение «24», как в 'int * p2 = aligned_alloc (1024, 1024 * sizeof * p2);' или 'int * p2 = aligned_alloc (10, 10 * sizeof * p2); '? Конечно, размер 'int' _could_ должен составлять 2,560, но я в этом сомневаюсь. – chux

+0

Возможно, это была опечатка, но код компилируется и работает нормально, как есть. Я использую GCC 4.9. – MichaelSB

+0

Для чего стоит, cppreference dot com, как правило, очень плохой источник информации о C++ и еще хуже для информации о C. Это больше похоже на чей-то неточный пересказ того, что говорят языки, а не на объяснение и разъяснение их требований. –

ответ

1

По your own reference:

Передача size, которое не является целым кратным alignment или alignment, которое не является действительным или не поддерживается реализацией вызывает функцию потерпеть неудачу и возвращает пустой указатель (C11 , как опубликовано, указанное неопределенное поведение в этом случае, это было исправлено DR 460).

Возможно компилятор, который принимает это в соответствии с правилами C11, не обновляясь для DR 460, и решил, что «неопределенный» означает «Работы» в этом случае. Конечно, это также может означать «Успехи, но не выравнивается или не выделяет минимальные байты выравнивания». Это не определено. пожимает

Для примера кода, оно могло быть написано до этого разъяснения и не приведены в соответствие с требованиями стандарта, или была опечатка писать его (как это было предложено в комментариях, возможно, он был предназначен, чтобы быть 1024 * sizeof *p2).

4

На самом деле, похоже, что стандарт C11 не может принять решение и постоянно меняет требования: изначально это было неопределенное поведение, а затем с DR 460 они изменили его на отказ и вернули нулевой указатель, и теперь это похоже на они хотят изменить его, чтобы принимать любые значения в качестве аргументов: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2072.htm

И, по-видимому, компиляторы не заботятся об этих ограничениях.

+1

Это действительно позор, что комитет по стандартизации изменил его, поэтому для использования в SIMD-приложениях, например, для выделения 64-битного массива 'float' с числом, не равным количеству -16, требуется сбой. Или для выделения большого буфера, согласованного с границей огромной страницы 2M. Это была единственная функция с хорошим API, которая возвращала указатели, которые вы могли бы передать «free». Приятно, что фактические реализации не соответствуют этому глупому дизайну, но это означает, что переносимое выровненное распределение еще не достижимо. –

+0

Требование о том, что размер должен быть кратным выравниванию, является глупым, учитывая, что все остальные функции распределителя могут выделять все, что они хотят, если оно больше или равно запрашиваемому размеру. Поэтому, даже если есть техническая причина для требования (мне любопытно, что это такое), aligned_alloc может просто округлить функцию внутри. Я также думаю, что аргумент выравнивания не должен быть требуемым выравниванием напрямую, а его логарифмом базы 2. Таким образом, для этой функции не было бы никаких недопустимых входов. – PSkocik

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

  • Нет связанных вопросов^_^