Странный вывод sizeof(struct) в C++

Может кто-нибудь объяснить, пожалуйста, вывод этого кода?

#include <iostream>
using namespace std;

struct Yo{
    char sex;
    int a;
};

int main() {
    Yo c;
    cout<<sizeof(c.sex);
    cout<<endl<<sizeof(c.a);
    cout<<endl<<sizeof(c);
    return 0;
}

Выход: 1 4 8

Каков размер структуры 8?

2 ответа

Решение

Из-за заполнения структуры (выравнивание памяти). Выравнивание должно быть степенью двойки (C11 делает это явным в 6.2.8p4, как заявлено @KeithThompson), и поскольку общий размер вашей структуры равен 5, ближайшее кратное 4 равно 8, так что это дает 8, также потому, что выравнивание должно быть степенью двойки.

Ты можешь использовать #pragma pack иметь точный размер.

#pragma pack(push, 1) /* set alignment to 1 byte boundary */
struct A {
    char s;
    int a;
};
#pragma pack(pop) // restore to default

Предупреждение: #pragma pack не в стандарте C, и при этом не предполагается, что структура требует 4-байтового выравнивания. Как сказал @KeithThompson.

"Размер типа должен быть кратным его выравниванию, но размер не должен быть степенью 2. Например, если предполагается 4-байтовое int, структура, подобная struct { int a, b; char d; } будет иметь выравнивание 4 и размер 12. Размер является ближайшим кратным выравнивания, а не ближайшей степенью 2." - @KeithThompson

Упаковка полезна для уменьшения памяти, используйте ее, когда у вас есть структура, полная целых чисел, фиксированной длины символов и т. Д. Я не знаю, хорошо ли это использовать с указателями, но я не вижу ее полезной при использовании указателя (например, void * в структуре).

Узнайте больше здесь

Это выравнивание памяти.

struct Yo{
    char sex;   // Takes up 1 byte + 3 for padding
    int a;      // Takes up 4 bytes
};

Три байта между sex а также a не будет использоваться, потому что компилятор выравнивает их для лучшей производительности. таким образом sex заканчивается использованием 1 байта пробела и три байта после переменной-члена используются как заполнение, чтобы гарантировать, что int a имеет адрес, кратный 4 (он выровнен на 4 байта).

Другие вопросы по тегам