Странный вывод 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 байта).