2

有人可以解释这段代码的输出吗?

#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的尺寸如何?

4

2 回答 2

4

这是内存对齐。

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 字节对齐的)。

于 2014-01-13T16:49:16.837 回答
1

因为结构填充(又名内存对齐)。对齐必须是 2 的幂(如@KeithThompson 所述,C11 在 6.2.8p4 中明确表示)并且由于结构的总大小为 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

打包对于减少内存很有用,当您有一个充满整数、固定字符长度等的结构时使用它。我不知道与指针一起使用是否很好,但我认为在使用指针时它没有用(例如 a void *in结构)。

在这里阅读更多

于 2014-01-13T16:52:53.287 回答