2016-08-28 8 views
0

В попытке понять выравнивание памяти C или что бы это ни было (выравнивание структуры данных?), Я пытаюсь написать код, который приводит к ошибке выравнивания. Первоначальная причина, по которой я узнал об этом, заключается в том, что я пишу код анализа данных, который считывает двоичные данные, полученные по сети. Данные содержат некоторые uint32s, uint64s, floats и double, и я хотел бы убедиться, что они никогда не повреждаются из-за ошибок в моем синтаксическом коде.Как продемонстрировать ошибку смещения памяти в C на macbook pro (процессор Intel 64 бит)

Неудачная попытка вызывают некоторые проблемы из-за перекос:

uint32_t integer = 1027; 
uint8_t * pointer = (uint8_t *)&integer; 
uint8_t * bytes = malloc(5); 
bytes[0] = 23; // extra byte to misalign uint32_t data 
bytes[1] = pointer[0]; 
bytes[2] = pointer[1]; 
bytes[3] = pointer[2]; 
bytes[4] = pointer[3]; 
uint32_t integer2 = *(uint32_t *)(bytes + 1); 
printf("integer: %u\ninteger2: %u\n", integer, integer2); 

На моей машине целых чисел печати то же самое. (macbook pro с 64-битным процессором Intel, не уверен, что именно определяет поведение выравнивания, это архитектура или точная модель процессора или компилятор, возможно, я использую Xcode так clang)

Я предполагаю, что мой процессор/машина/настройка поддерживает unaligned читает, поэтому он берет вышеуказанный код без каких-либо проблем.

Что произойдет, если синтаксический анализ, например, uint32_t, потерпит неудачу из-за неправильного совпадения кода? Есть ли способ сделать его неудачным на современной 64-разрядной системе Intel? Или я могу избежать ошибок выравнивания при использовании простых типов данных, таких как целые числа и плавающие элементы (без структур)?

Edit: Если кто-то читает это позже, я нашел подобный вопрос с интересной информацией: Mis-aligned pointers on x86

+7

На x86 отсутствуют требования к выравниванию. Это помогает в производительности, но это не требуется. –

+0

Итак, я могу бросить байтовые массивы, а uint32s поплавки удваивает uint64s и никогда не будет иметь коррупции? –

+0

Это не особо конкретный вопрос. Как я уже сказал, вы ничего не можете сделать, поскольку выравнивание типов данных приведет к ошибке. –

ответ

1

Обычно, архитектура x86 не имеет требования к выравниванию [для некоторых инструкций SIMD, как movdqa исключения).

Однако, поскольку вы пытаетесь писать код, чтобы вызвать такое исключение ...

Существует выравнивания проверки исключение бит, который может быть установлен в x86 регистре флагов. Если вы замыкаетесь в, невыровненный доступ будет генерировать исключение, которое будет отображаться [под Linux, по крайней мере] как ошибка шины (т.е. SIGBUS)

Смотрите мой ответ здесь: any way to stop unaligned access from c++ standard library on x86_64? подробности и некоторые примеры программ для генерации исключение.