2012-04-26 3 views
6

Я получаю необычное поведение с моим кодом, который является следующимПоведения SizeOf оператора в C

#include<stdio.h> 
struct a 
{ 
    int x; 
    char y; 
}; 
int main() 
{ 
    struct a str; 
    str.x=2; 
    str.y='s'; 
    printf("%d %d %d",sizeof(int),sizeof(char),sizeof(str)); 
    getch(); 
    return 0; 
} 

Для этого куска кода я получаю выход:

4 1 8 

На моем знания структура содержит целочисленную переменную размера 4 и переменную char размером 1, поэтому размер структуры a должен быть 5. Но как получится размер структуры 8. Я использую визуальный компилятор C++. Зачем это поведение?

+2

В аргументах 'printf()' вы действительно должны вводить значения 'sizeof' в' (int) '... или' (unsigned long) 'и использовать' '% lu" '... или, если вы C99, используйте ''% zu''. – pmg

+2

@pmg: Точно. Поскольку 'sizeof()' возвращает значение типа 'size_t'. –

ответ

12

Это называется Structure Padding

Имея структуры данных, которые начинаются на 4 байта выравнивания слова (на процессорах с 4-байтовых автобусов и процессоров) является гораздо более эффективным, когда перемещение данных вокруг памяти, а также между RAM и CPU.

Вы можете, вообще говоря, отключить это с помощью параметров компилятора и/или прагм. Специфика этого будет зависеть от вашего конкретного компилятора.

Надеюсь, это поможет.

+1

_Вы можете вообще отключить это off_, но я рекомендую никогда не делать этого, даже если вам нужно проанализировать некоторый бинарный пакет и иметь идею создать подобную структуру для легкого кодирования/декодирования. Помните, что на некоторых объектах (возможно, только в прошлом) неудовлетворенное чтение может привести к сбою процессора! Также это делает ваш код полностью незарегистрированным. – Yury

+0

@Yury: если компилятор разрешает '#pragma pack' или подобные вещи на таких платформах, как правило, он будет генерировать код для обхода проблемы согласованного чтения (обычно« memcpy »в отдельное выровненное местоположение), в противном случае такие структуры непригодны для использования , –

8

Компилятор вставляет прокладку для оптимизации и оптимизации. Здесь компилятор вставляет 3 фиктивных байта между (или после) ваших обоих членов.

Вы можете обработать выравнивание с помощью директивы #pragma.

+1

возможно (1) 3 байта и (2) после – Vlad

+0

Да, это 3 байта в этом случае, но я думаю, что это между, не так ли? – md5

+0

хорошо, это зависит от контентоспособности целевой машины :) либо iiiidddc, либо iiiicddd. – Vlad

0

В основном, чтобы проиллюстрировать, как это дополнение работает, я немного изменил вашу программу.

#include<stdio.h> 
struct a 
{ 
    int x; 
    char y; 
    int z; 
}; 
int main() 
{ 
    struct a str; 
    str.x=2; 
    str.y='s'; 
    str.z = 13; 

    printf ("sizeof(int) = %lu\n", sizeof(int)); 
    printf ("sizeof(char) = %lu\n", sizeof(char)); 
    printf ("sizeof(str) = %lu\n", sizeof(str)); 

    printf ("address of str.x = %p\n", &str.x); 
    printf ("address of str.y = %p\n", &str.y); 
    printf ("address of str.z = %p\n", &str.z); 

    return 0; 
} 

Обратите внимание, что я добавил к структуре третий элемент. Когда я запускаю эту программу, я получаю:

[email protected]:~/so$ ./padding 
sizeof(int) = 4 
sizeof(char) = 1 
sizeof(str) = 12 
address of str.x = 0x7fffc962e070 
address of str.y = 0x7fffc962e074 
address of str.z = 0x7fffc962e078 
[email protected]:~/so$ 

Часть этого, которая иллюстрирует заполнение, подсвечена ниже.

address of str.y = 0x7fffc962e074 
address of str.z = 0x7fffc962e078 

Хотя y является только одним символом, обратите внимание, что z является полным 4 байтами.

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