可能有些蒟蒻(像我一样),看了别人的博客以后还是不明白“字节对齐”是什么意思,这里我谈谈我的理解,可能有错误,但测试结果应该没问题。
————————————————————正文————————————————————
先来个引例:
#include<stdio.h>
struct{
char c1;
char c2;
int i1;
}x1;
struct{
char c1;
int i1;
char c2;
}x2;
int main()
{
printf("%d\n",sizeof(x1));
printf("%d\n",sizeof(x2));
return 0;
}
输出结果如下:
可以见到,第一第二个结构体的大小出现了差别。
但这是为什么呢,结构体的大小怎么计算呢?
原理可以参考理一理字节对齐的那些事 - 知乎。
这里主要阐释其中的对齐规则,也就是如何计算结构体的大小。
计算步骤如下:
1.找到占内存最大的变量类型(忽略结构体变量,包括步骤3的计算也不用考虑结构体变量,步骤4再考虑,这里指的是基本变量像int,float之类的)
2.按照这个变量的大小开辟空间。
3.开辟空间之后依次放入后面的变量,直到放不进这个变量就再开一个这样的空间。
4.最后加上其他结构体变量的大小(如果有)。
———————————————————————————————————————————
最后结合实例看看怎么计算,比如我们看这个结构体x2的大小:
#include<stdio.h>
struct node
{
char c1;
char c2;
int i1;
}x1;
struct{
char c1;
char c2;
long long ll;
struct node b;
struct node *a;
}x2;
int main()
{
printf("%d\n",sizeof(x2));
return 0;
}
我们发现结构体x2中包含了结构体node定义出来的a,所以先算node的大小。
node中最长的是int类型的i1,大小为4(极少数版本还是用的2,这里按4计算)。
先开辟大小为4的空间(取决于结构体中最大内存占用数的类型),c1一个字节可以放入。
这时开辟的空间还剩下三个字节,c2也可以放入。
之后开辟的空间还有两个字节,不够放入四个字节的i1。
于是再开辟4个字节的空间放入i1。
所以node类型的大小为4+4=8(字节);
之后再算先计算x2的大小,一样,找到最大的long long是8字节。
开辟大小为8的空间,可以放入c1,c2。剩下6字节的空间放不下之后的ll变量。
再开辟大小为8的空间放入ll变量,没有剩余空间放入后面的结构体针变量a(4个字节)。
再开辟8的空间放a。
最后加上结构体node的大小8。
计算结果为8+8+8+8 = 32。
我理解的过程大致如上,总之就是注意结构体中包括的结构体变量要最后考虑,其他变量看看是不是能放入之前开辟的空间里,放不下就继续开辟。
语言略为啰嗦,阐述可能有些混乱,还请谅解。
参考资料:
C语言 --- sizeof() 7种使用详解-CSDN博客
写于2024年1月3日。