C语言:结构体——关于内存字节对齐图文详解

前言:

我们在学到c语言内存管理的时候总是一遍惊叹,其聪明的内存管理策略,一遍抱怨其难以理解的方法,网上的资料要不讲究的太详细,要不没能讲解清楚,今天我们根据实例来学习一下基于32位操作系统的的C语言:内存字节对齐

tip:在32位编译模式下,默认以4字节对齐;在64位编译模式下,默认以8字节对齐。

目录

1. 什么是对齐?

2. 计算机为什么要对齐?

 3.我们直接上代码

案例一

 案例二

对齐规律 

名词解释:

对齐有两个规则:


1. 什么是对齐?

  现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序地一个接一个地排放,这就是对齐。

2. 计算机为什么要对齐?

  各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取,其他平台可能没有这种情况。但是如果不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。

例如一个 int 类型的数据,如果地址为 8,那么很好办,对编号为 8 的内存寻址一次就可以。如果编号为 10,就比较麻烦,CPU需要先对编号为 8 的内存寻址,读取4个字节,得到该数据的前半部分,然后再对编号为 12 的内存寻址,读取4个字节,得到该数据的后半部分,再将这两部分拼接起来,才能取得数据的值。

将一个数据尽量放在一个步长之内,避免跨步长存储,这称为内存对齐。在32位编译模式下,默认以4字节对齐;在64位编译模式下,默认以8字节对齐。

 3.我们直接上代码

案例一

#include <stdio.h>

void main(){

    struct A{
        char a;
        short b;
        int c;
    };

    printf( "size of struct A = %d \n", sizeof(struct A) );

}

输出结果为:8字节。

我们来看图

第一步:

首先自身对齐值最大(也就是int型)是4  32位操作系统的对齐值也是4,所以有效对齐值就是4

第二步:

满足存放成员的起始地址必须是该成员有效对齐值的整数倍

a是char型数据,占用1字节内存;short型数据,占用2字节内存;int型数据,占用4字节内存。因此,结构体A的自身对齐值为4。于是,a和b要组成4个字节,以便与c的4个字节对齐。而a只有1个字节,a与b之间便空了一个字节。我们知道,结构体类型数据是按顺序存储结构一个接一个向后排列的

 案例二

#include <stdio.h>

void main(){

    struct A{
        short b;
        int c;
        char a;
    };

    printf( "size of struct A = %d \n", sizeof(struct A) );

}

输出结果为:12字节。

我们来看图

第一步:

自身对齐值最大(也就是int型)是4  32位操作系统的对齐值也是4,所以有效对齐值就是4

第二步:

满足存放成员的起始地址必须是该成员有效对齐值的整数倍

b是short型数据,占用2字节内存;chart型数据,占用1字节内存;int型数据,占用4字节内存。因此,结构体A的自身对齐值为4。于是,b一个数据占4字节(原本是两个字节),c一个数据占4字节,a一个数据占4字节(原本一个字节)

类比成这样子(对齐的样子)

对齐规律 

名词解释:

这里引入四个概念

数据类型自身的对齐值,

指定对齐值,

结构体或者类的自身对齐值,

数据成员、结构体和类的有效对齐值

  1)数据类型自身的对齐值:就是基本数据类型的自身对齐值,比如char类型的自身对齐值为1字节,int类型的自身对齐值为4字节。

  2)指定对齐值:预编译命令#pragma pack (value)指定的对齐值value。

  3)结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值,比如以上的struct A的对齐值为4。

  4)数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小的那个值。

对齐有两个规则:


1、首先 结构体的自身对齐值操作系统的对齐值相比的那个就是有效对齐值

比如下面这个 结构体的自身对齐值是4 操作系统的对齐值也是4,所以有效对齐值就是4   

#include <stdio.h>

void main(){

    struct A{
        short b;
        int c;
        char a;
    };

    printf( "size of struct A = %d \n", sizeof(struct A) );

}


2、满足存放成员的起始地址必须是该成员有效对齐值的整数倍。

通俗来说就是每一个数据类型有效对齐值相比                 取大的那个值就是最后的有效对齐值

#include <stdio.h>

void main(){

    struct A{
        short b;
        int c;
        char a;
    };

    printf( "size of struct A = %d \n", sizeof(struct A) );

}

还是上面的代码,b为short型(1字节)和有效对齐值(4字节)相比取大的值就是4字节

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
C语言结构体字节对齐规则是根据结构体中的成员变量的类型和对齐值来确定的。对于一个结构体来说,它的自身对齐值是结构体中所有成员变量中的最大对齐值。而结构体的有效对齐值是结构体的自身对齐值和操作系统的对齐值中的较小值。 在给定的例子中,结构体A中包含了一个short型变量b、一个int型变量c和一个char型变量a。根据引用\[2\]中的解释,short型变量占用2字节,int型变量占用4字节,char型变量占用1字节。因此,结构体A的自身对齐值为4字节。 根据引用\[3\]中的解释,结构体A的有效对齐值是结构体的自身对齐值和操作系统的对齐值中的较小值。在这个例子中,操作系统的对齐值也是4字节。所以,结构体A的有效对齐值也是4字节。 因此,根据C语言结构体字节对齐规则,结构体A中的成员变量a和b要组成4个字节,以便与成员变量c的4个字节对齐。由于成员变量a只占用1个字节,所以在a和b之间会有一个字节的空隙。 总结起来,C语言结构体字节对齐规则是根据结构体中的成员变量的类型和对齐值来确定的,以保证结构体的对齐要求和内存的高效利用。 #### 引用[.reference_title] - *1* *2* *3* [C语言结构体——关于内存字节对齐图文详解](https://blog.csdn.net/qq_62932195/article/details/125821103)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heart_6662

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值