Компилятор (G ++), кажется, выделяет больше памяти для экземпляров классов, чем ему нужно - PullRequest
10 голосов
/ 04 ноября 2011

Я узнаю о том, как компиляторы представляют программы на C ++ в ассемблере.У меня есть вопрос о том, что делает компилятор, что я не могу понять.Вот некоторый код C ++:

class Class1 {
public:
  int i;
  char ch;
};

int main() {
  Class1 cls;
}

Компиляция с "g ++ -S" выводит это (я удалил все, кроме определения функции):

main:
    push    ebp
    mov     ebp, esp
    sub     esp, 16
    mov     eax, 0
    leave
    ret

Я непонять строку sub esp, 16.Зачем ему выделять 16 байтов для экземпляра этого класса, который требует только 8, если принять во внимание выравнивание и заполнение структуры данных ?

Это должно быть

[int i - 4 bytes][char ch - 1 byte][padding - 3 bytes]

не так ли?

Когда я скомпилировал код с определением класса, включающим также double, то есть

class Class1 {
public:
  int i;
  char ch;
  double dub;
}; 

он все еще выделил 16 байтов, что имело смысл в этом случае.

Так почему компилятор выделяет 16 байтов, когда ему нужно только 8?

1 Ответ

12 голосов
/ 04 ноября 2011

Это связано с выравниванием стека, а не с выравниванием структуры.

Если вы сделали sizeof() для своих объектов, вы увидите, что ожидаете с выравниванием структуры и заполнением.

Однако стековые фреймы немного отличаются.В большинстве современных систем выравнивание стека составляет 16 байтов (или более) для обеспечения доступа к памяти SSE.

...