Понимание размера структуры C ++ - PullRequest
7 голосов
/ 09 января 2011

Рассмотрим следующий код:

struct CExample  {
    int a; 
}            

int main(int argc, char* argv[]) {  

    CExample ce1;  
    CExample ce2;  

    cout << "Size:" << sizeof(ce1) << " Address: " << &ce1 << endl;   
    cout << "Size:" << sizeof(ce2) << " Address: " << &ce2 << endl;   

    CExample ceArr[2];
    cout << "Size:" << sizeof(ceArr[0])<< " Address: "<< &ceArr[0] <<endl;
    cout << "Size:" << sizeof(ceArr[1])<< " Address: "<< &ceArr[1] <<endl;

    return 0;
}

Пример вывода:
ce1: размер = 4, адрес: 0039FAA0
ce2: размер = 4, адрес: 0039FA94
ceArr [0]: размер = 4, адрес: 0039FA84
ceArr [1]: размер = 4, адрес: 0039FA88

В коде между адресами первых двух объектов (ce1 и ce2) имеется 12-байтовый код, но разница между объектами в массиве составляет всего 4 байта.

Я думал, что выравнивание данных как-то связано с этой проблемой, но я все еще в замешательстве. Есть идеи, что на самом деле здесь происходит?

Ответы [ 4 ]

15 голосов
/ 09 января 2011

Поскольку объекты в массиве должны быть смежными. Объекты, объявленные последовательно в стеке (в исходном коде, а не в машине), [не должны быть смежными], хотя они могут быть.

6 голосов
/ 09 января 2011

Стандарт ничего не говорит об этом. Компилятор может свободно вставлять любые отступы между элементами.

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

1 голос
/ 09 января 2011

Компилятор не только использует стек для хранения ваших локальных переменных - он также использует его, например, для передачи аргументов, а также некоторые накладные расходы, вызванные std::cout.Вероятно, именно для этого используется дополнительный пробел между вашими переменными.

Если вместо этого вы сделаете свои переменные static, например:

static CExample ce;
static CExample ce2;

static CExample ceArr[2];

... переменные будут помещены вВместо этого BSS, и выравнивание, скорее всего, будет тем, что вы ожидаете.

Причина, по которой массивы упакованы, а отдельные элементы нет, выясняется другими ответами ...

0 голосов
/ 09 января 2011

Причина в том, что на большинстве архитектур невыровненные нагрузки медленные.См. Статью в Википедии о выравнивании структуры данных для хорошего объяснения.Компилятор размещает каждую из ваших структур данных в начале слова данных.Однако в массивах элементы размещаются в памяти непрерывно (как того требует стандарт C ++).

...