字节对齐
1.struct A{
int a;
char b;
short c;
};sizeof(A)是多少?
2.struct A
{
int a;
char b【10】;
short c;
};sizeof(A)是多少?4+12=16?
1. 首先,我们需要了解字节对齐的概念。字节对齐是指在内存中存储数据时,变量的起始地址必须是其类型大小的整数倍。这是为了提高内存读取的效率。
对于第一个结构体A来说,int类型占4个字节,char类型占1个字节,short类型占2个字节。按照字节对齐的原则,int类型的起始地址是4的倍数,char类型的起始地址是1的倍数,short类型的起始地址是2的倍数。所以,为了满足字节对齐的要求,编译器会在char类型后面填充3个字节,将short类型的起始地址对齐。因此,结构体A的大小为4 + 1 + 3 + 2 = 10个字节。
所以,sizeof(A)的结果是10。
2. 对于第二个结构体A来说,int类型占4个字节,char类型占10个字节,short类型占2个字节。按照字节对齐的原则,int类型的起始地址是4的倍数,char类型的起始地址是1的倍数,short类型的起始地址是2的倍数。所以,为了满足字节对齐的要求,编译器会在char类型后面填充2个字节,将short类型的起始地址对齐。因此,结构体A的大小为4 + 10 + 2 = 16个字节。
所以,sizeof(A)的结果是16。
希望这个解答能够帮到你!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 本帖最后由 jackz007 于 2024-1-2 21:26 编辑
#include <stdio.h>
int main(void)
{
struct A {
inta ; // a 从偏移 0 的位置开始,正常占用 4 个字节
char b ; // b 从偏移为 4 的位置开始,占用 1 个字节
short c ; // c 本应从偏移 5 的位置开始,但是,由于 c 占用 2 个字节,必须从 2 的整数倍偏移位置开始,所以,c 从偏移为 6 的位置开始,占用 2 个字节
} ; // struct A 一共需要占用 8 个字节
struct B {
int a ; // a 从偏移 0 的位置开始,正常占用 4 个字节
char b ; // b 从偏移为 4 的位置开始,占用 10 个字节
short c ; // c 从偏移为 14 的位置开始,占用 2 个字节
} ; // struct B 一共需要占用 16 个字节
printf("the sizeof(struct A) is %d\n" , sizeof(struct A)) ;
printf("the sizeof(struct B) is %d\n" , sizeof(struct B)) ;
}
更加有意思的是,一模一样的两个结构,仅仅因为成员顺序不同,从而导致占用空间存在较大差异:
#include <stdio.h>
int main(void)
{
struct A {
char a ; // a 从偏移 0 的位置开始,正常占用 1 个字节
long long b ; // b 本应从偏移为 1 的位置开始,由于 b 需要占用 8 个字节,需要从 8 字节对齐的位置开始,所以,b 从偏移 8 开始,占用 8 个字节
short c ; // c 从偏移为 16 的位置开始,占用 2 个字节
int d ; // d 本应从偏移为 18 的位置开始,但是,由于 d 占用 4 个字节,需要从 4 字节对齐的位置开始,所以,d 从偏移 20 开始,占用 4 个字节
} ; // struct A 一共需要占用 24 个字节
struct B {
char a ; // a 从偏移为 0 的位置开始,正常占用 1 个字节
short c ; // c 本应从偏移为 1 的位置开始,由于 c 需要占用 2 个字节,需要从 2 字节对齐的位置开始,所以,c 从偏移 2 开始,占用 2 个字节
int d ; // d 从偏移为 4 的位置开始,占用 4 个字节
long long b ; // b 从偏移为 8 的位置开始,占用 8 个字节
} ; // struct B 一共需要占用 16 个字节
printf("the sizeof(struct A) is %d\n" , sizeof(struct A)) ;
printf("the sizeof(struct B) is %d\n" , sizeof(struct B)) ;
}
而所有这一切,都是因为边界对齐所致。
jackz007 发表于 2024-1-2 20:22
更加有意思的是,一模一样的两个结构,仅仅因为成员顺序不同,从而导致占用空间存在较大差异:
...
你是al吗? liyifeng295641 发表于 2024-1-3 20:17
你是al吗?
不是,我是活人! jackz007 发表于 2024-1-3 21:51
不是,我是活人!
{:10_257:} liyifeng295641 发表于 2024-1-3 21:52
能看明白我的解释吗? jackz007 发表于 2024-1-3 21:53
能看明白我的解释吗?
不能的 liyifeng295641 发表于 2024-1-3 21:54
不能的
哪里看不懂? jackz007 发表于 2024-1-3 21:55
哪里看不懂?
偏移, 本帖最后由 jackz007 于 2024-1-4 08:21 编辑
liyifeng295641 发表于 2024-1-3 21:59
偏移,
其实,很容易理解,你可以把结构体视为一把有刻度的尺子,结构体开始位置的刻度为 0,刻度的单位为字节,你还可以把结构体的成员想象为有长度的线段,例如,int 型成员占用 4 个字节,那么,它就是一条长度为 4 的线段,所有的成员需要按照各自在结构体中的先后顺序在这把“尺子”上“排队”,而且,彼此互不重叠。例如,有个结构体,有 a、b、c 三个 int 型的成员,则它们会彼此首尾相接,以 a、b、c 的先后顺序,无缝拼接成为一条长度为 12 的线段,如果用尺子来衡量,则 a、b、c 分别开始于 0、4、8,这就是我们所说的偏移。
假如,又有一个结构体,有 a、b 两个成员,其中,成员 a 是 char 型,长度为 1 ,那么,它会占据刻度 0~1,第二个成员 b
是 long long 型,其长度为 8,本应占据刻度 1~9,但是,按照字节边界对齐的规则,其开始位置必须是 8 的倍数,于是,成员 b 便实际占用了刻度 8~16,这样,由于字节边界对齐的原因,成员 a 和 b 未能首尾相接,而是以间断的状态占据了尺子 0~16 的刻度区间,其中,在1~8 的刻度位置是一个“缺口”。
页:
[1]