【C语言】结构体内存对齐详解

文章详细解释了结构体内存对齐的规则,即成员变量对齐到对齐数的整数倍地址,结构体大小为最大对齐数的整数倍。通过示例分析了s1、s2、s3三个结构体的内存布局,强调了内存对齐对于平台兼容性和程序性能的重要性。
摘要由CSDN通过智能技术生成

1、结构体内存对齐规则

先来让我们来了解一下结构体内存对齐的规则

  1. 第一个成员在与结构体变量偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。(如果编译器没有默认对齐数,那对齐数>就是成员自身的对齐数)
  3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍,也就是说结构体大小不能小于其最大成员大小;
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
    体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍

2、结构体内存对齐示例

#include <stdio.h>
struct s1
{
    char c;
    int i;
    short s;
};
struct s2
{
    double d;
    float f;
    struct s1 A;
};
struct s3
{
    struct s1 B;
    struct s2 C;
    char str[10];
};

int main()
{
    printf("Size of s1: %d\n", sizeof(struct s1));
    printf("Size of s2: %d\n", sizeof(struct s2));
    printf("Size of s3: %d\n", sizeof(struct s3));
    return 0;
}

来看一下它的输出结果
在这里插入图片描述

先来分析一下s1

c是char型,占1个字节,对应到结构体变量偏移量为0 的地址处。
i是int型,占4个字节,对齐数就是4,对齐到4的整数倍位置处,即偏移量为4开始的地址处。
s是short型,占2个字节,对齐到1 的整数倍,那就是下一个地址空间,对齐到偏移量为8的地址空间。
结构体总大小为最大对齐数的整数倍,最大对齐数为4,故总大小是4的整数倍,那么总大小就是12个字节,所以输出结果是12。

再来看一下图解

在这里插入图片描述

再来看一下s2

d是double型,占8个字节,对应到结构体变量偏移量为0 开始的地址处。
f是float型,占4个字节,对齐数就是4,对齐到4的整数倍位置处,即偏移量为8开始的地址处。
s1是结构体,占12个字节,对齐到自己的最大对齐数的整数倍处(即对齐数是4),对齐到4的整数倍的位置,即偏移量为12开始的地址处。
结构体总大小为最大对齐数的整数倍(包含s1的成员的最大对齐数),最大对齐数为8,故总大小是8的整数倍,那么总大小就是24个字节,所以输出结果是24。

图解如下图

在这里插入图片描述

分析一下s3的内存

s1是结构体,占12个字节,对应到结构体变量偏移量为0 开始的地址处。
s2是结构体,占24个字节,对齐数就是8,对齐到8的整数倍位置处,即偏移量为16开始的地址处。
str[10],是char类型,占10个字节,对齐数是1,对齐到1的整数倍的位置,即偏移量为40开始的地址处
结构体总大小为最大对齐数的整数倍(包含s1和s2的成员的最大对齐数),最大对齐数为8,故总大小是8的整数倍,那么总大小就是56个字节,所以输出结果是56。

3、结构体内存对齐的原因

  1. 平台原因(移植原因):
    主要是由于不同的硬件平台对于不同数据类型的访问是有限制的。不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特
    定类型的数据,否则抛出硬件异常。因此,在这些平台上,结构体成员的布局必须满足一定的对齐要求,以确保访问这些成员时可以正常工作。
  1. 性能原因:
    数据结构(尤其是栈)应该尽可能地在自然边界上对齐。
    原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访
    问。因此,通过对结构体进行内存对齐,可以减少处理器的访存时间,并提高程序的执行效率。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值