鱼C论坛

 找回密码
 立即注册
查看: 894|回复: 10

[已解决]字节对齐

[复制链接]
发表于 2024-1-2 18:26:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
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?









最佳答案
2024-1-2 20:22:35
本帖最后由 jackz007 于 2024-1-2 21:26 编辑
#include <stdio.h>

int main(void)
{
        struct A {
            int  a     ; // 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[10] ; // 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)) ;
}
        而所有这一切,都是因为边界对齐所致。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-1-2 18:26:56 | 显示全部楼层
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]类型占10个字节,short类型占2个字节。按照字节对齐的原则,int类型的起始地址是4的倍数,char[10]类型的起始地址是1的倍数,short类型的起始地址是2的倍数。所以,为了满足字节对齐的要求,编译器会在char[10]类型后面填充2个字节,将short类型的起始地址对齐。因此,结构体A的大小为4 + 10 + 2 = 16个字节。

所以,sizeof(A)的结果是16。

希望这个解答能够帮到你!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-2 20:22:35 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2024-1-2 21:26 编辑
#include <stdio.h>

int main(void)
{
        struct A {
            int  a     ; // 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[10] ; // 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)) ;
}
        而所有这一切,都是因为边界对齐所致。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-3 20:17:11 | 显示全部楼层
jackz007 发表于 2024-1-2 20:22
更加有意思的是,一模一样的两个结构,仅仅因为成员顺序不同,从而导致占用空间存在较大差异:
...

你是al吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-3 21:51:51 | 显示全部楼层

      不是,我是活人!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-3 21:52:55 | 显示全部楼层
jackz007 发表于 2024-1-3 21:51
不是,我是活人!

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-3 21:53:46 | 显示全部楼层

        能看明白我的解释吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-3 21:54:46 | 显示全部楼层
jackz007 发表于 2024-1-3 21:53
能看明白我的解释吗?

不能的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-3 21:55:51 | 显示全部楼层

        哪里看不懂?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-3 21:59:17 | 显示全部楼层

偏移,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-3 22:19:23 | 显示全部楼层
本帖最后由 jackz007 于 2024-1-4 08:21 编辑


       其实,很容易理解,你可以把结构体视为一把有刻度的尺子,结构体开始位置的刻度为 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 的刻度位置是一个“缺口”。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-3 10:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表