2016-06-21 2 views
-1

Привет Я понимаю, что в стандарте C требуется выравнивание по памяти при выполнении sizeof. Но я не совсем понимаю, почему даже целые массивы должны быть выровнены. Смотрите мой следующий пример:c sizeof integer выравнивание?

#include <stdio.h> 

struct flexarray { 
    int a[2]; 
    double f; 
}; 

int main(int argc, char** argv) 
{ 
    printf("sizeof (struct flexarray) = %zu\n", sizeof (struct flexarray)); 
    return 0; 
} 

выход 16, потому что sizeof(int) = 4 и sizeof(double) = 8. Это нормально.

Но когда я меняю a на int[3], тогда вывод равен 24 Это не то, что я ожидаю, потому что согласно моему расчету результат должен быть 20 (= 3 x 4 + 8).

Единственное объяснение, о котором я мог думать, это то, что компилятор добавляет целочисленное целое число, но я не понимаю, почему это происходит: sizeof(int[3]) равно 12, и в конце концов оно кратно 4 байтам.

Я компилирую на 32-разрядный Linux с gcc.

Linux 93c9e1096795 3.10.0-327.10.1.el7.x86_64 #1 SMP Tue Feb 16 17:03:50 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux 

Может кто-нибудь сказать мне, почему?

+0

«Привет, я понимаю, что стандарт C требует выравнивания памяти при выполнении' sizeof' »- Ehm, no! Что означает 'sizeof' для выравнивания? В первую очередь они не связаны. – Olaf

+0

Выравнивание связано с доступом к памяти. Это не относится к стандарту 'sizeof' или C вообще, кроме того, что влияет на размеры структуры и делает размер структуры отличным. –

+0

Похоже, что удвоения должны быть выровнены по 8-байтовым границам на вашей платформе. Таким образом, 4 байта заполнения должны быть вставлены после вашего массива 'int [3]' для достижения этого. Кажется достаточно ясным. –

ответ

3

Если вы используете offsetof для проверки положения членов класса, вы, скорее всего, обнаружите, что компилятор хочет выровнять значения double на 8-байтных границах.

+0

C не поддерживает классы. Чтобы проверить выравнивание, используйте '_Alignof' /' alignof', а не 'offsetof'. – Olaf