结构体数组中的内存对齐问题

4
我有一个定义如下的结构体数组:
struct { int x; char y; } arr[10];
在我的机器上,int类型占用4个字节,char类型占用1个字节。我知道这些结构体会在内部填充,也就是说每个数组元素的大小将为8个字节。但是我想知道:
1) 这是因为下一个数组元素中的int类型成员需要对齐要求,还是
2) 因为由于结构体类型变量的自然对齐要求,每个结构体本身都应该对齐在8字节边界上。
为了让我的观点更清晰,第一个数组成员的起始地址应该是什么? 如果它是一个8字节对齐的地址,正如第二种情况所指出的那样,这可能会成为定义大型二维数组时的问题,例如:
int arr[1000][1000];
这里,每个二维数组元素(即每个一维数组)应该在4000字节边界上对齐。机器可能没有足够内存来满足这种内存需求。

哪种编程语言? - Raedwald
这是C语言。如果我对一个单独定义的结构体实例(而不是结构体数组的元素)应用sizeof,得到的答案是8字节而不是5字节。为什么会这样?即使在单个实例的情况下,当内存空闲时,编译器是否也填充了内存? - Maxx.ag
1个回答

5

我不确定我理解你提到的两个选项之间的区别。

C++中的每种类型都有一个自然对齐方式,其大小是多个字节的倍数。但对齐方式不一定等于对象的大小。

例如,int类型通常具有4个字节的自然对齐方式和4个字节的大小。

但是,虽然1000个int的数组的大小为4000字节,但它仍然只需要4字节的对齐方式。

复合类型(结构体和数组)仅需要与它们最对齐成员相同的对齐方式。1000个int的数组仅包含一种类型的对象:int。而该类型需要4字节对齐方式,因此整个数组也仅需要4字节对齐方式。

同样对于您的示例结构体,它的大小通常为8个字节,但它由int(需要4字节对齐)和char(需要1字节对齐)组成。因此,任何成员所需的最严格对齐方式为4,因此结构体需要4字节对齐方式。


非常感谢!我对这个概念有点困惑。另外,如果我在单独定义的结构体实例上应用 sizeof(而不是结构体数组的元素),我得到的答案是 8 字节,而不是 5 字节。为什么会这样? - Maxx.ag
1
是的,这是由于数组中的元素之间不能有填充的另一个规则造成的。因此,假设您创建了一个包含结构体的数组。每个元素都必须对齐到 8 字节边界,但如果大小为 5,则第二个元素将放置在 5 字节边界上。因此,为确保每个元素都放置在 8 字节边界上,需要将大小设置为对齐要求的倍数。 - jalf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接