C语言结构体占字节数问题

今天在刷C语言结构体的一个题,是计算结构体字节数的。搞不清原理,求大佬指点...
题:

#include <stdio.h>
int main()
{
typedef struct{
    int a;
    char s[10];
    }TYPE;
TYPE ul;
int a;
char s1[10];
printf("%d\n",sizeof(ul));
//长度为16

}

请问为什么结果是16啊? int 占4字节, s[10]我原以为占10字节,结果后来知道占1字节。那应该是4+1=5啊。为什么是16呢?

阅读 3.5k
3 个回答

这叫做 padding 。

先说一下,char s[10]; 确实要占10字节,而不是 1 字节。

然后继续说 padding 。padding 就是要数据结果中补充几个不表示任何数据的字节,使其中元素的地址可以一定出现的特定的地址上。

这是因为,在很多计算机体系结构中,对不同内存地址的访问速度是不同的。比如,从 4 的倍数的位置读取一个 int (4 字节),可能会比从其他地址读取同样长度的字节快,而且可能快很多。(在某些体系结构里,从不是 4 的倍数的地址读取 int 甚至会直接导致程序挂掉。)于是,编译器就会尽可能的把 int 放在 4 的倍数的地址上。

但是,组成 struct 之后,比如这里,如果 struct 长度是 14 字节,那么当这个 struct 形成一个数组的时候,必然至少有一半 a 并不是在 4 的倍数的地址上的。怎么办呢,编译器于是在这个结构体中增加了两个不表示任何数据的字节(padding),把 struct 的长度 pad 到 16 ,这样就可以保证这个 struct 的数组中,可以把每一个 a 都放在 4 的倍数的地址上。

这个实在结尾的 padding ,padding 也可能出现在 struct 中,如 struct {char a; int b;}; ,a 后很有可能会被 pad 3 个字节,最后结构体大小为 8 字节。

最后,padding 是与编译器、操作系统、体系结构有关的。同一段程序在不同的地方可能会有不同的 padding 结果(从而有不同的大小)。

新手上路,请多包涵

具体可以看这里https://blog.csdn.net/yanyumi...
大意就是结构体在存储时候会对齐偏移量,所以一定是偏移量的整数倍,4+10=12所以对齐到16

不同编译器和编译参数,不同操作系统上的结果是一样的,对于32位cpu,cpu是以32位为单位从内存读取数据,所以读取地址如果是4的整数倍,速度会快,如果地址不是4的整数倍,就跨越两个字,cpu要读两次才能把数据读出来,速度就慢两倍。

所以c优化编译器,如果设置的字节边界优化参数,会自动把数据的地址安排在4整数倍上,结构体长度也设置为4的整数倍,这样会提高运行速度。

你可以百度一下c的字节对齐和边界对齐优化

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进