美文网首页
C语言 内存对齐

C语言 内存对齐

作者: 付凯强 | 来源:发表于2022-04-27 12:49 被阅读0次

引言

先看一个例子:

typedef struct Test
{
    char a1;
    int a2;
}Test_T;

请问Test_T占几个字节?
如果你的回复是 1 + 4 = 5,那就错了。
我们看下程序运行的结果:

Test_T T;
printf("\nsizeof(T) = %lu\n", sizeof(Test_T));
printf("a1地址:%p\n", &T.a1);
printf("a2地址:%p\n", &T.a2);

sizeof(T) = 8
a1地址:0x7ffd65f12e40
a2地址:0x7ffd65f12e44

程序给出的答案是8个字节。

内存对齐

所谓内存对齐指的是对占用内存较少的类型变量进行内存补齐,对齐占用内存较多的类型变量。在引言中,当char和int放在一起的时候,char自动补齐为4个字节,int占用也是4个字节,加起来就是8个字节。
按照这个理论,那么char和short放在一起,那应该是char自动补齐为2个字节,short两个字节,加起来一共是4个字节。

typedef struct Test
{
    char a1;
    short a2;
}Test_T;
sizeof(T) = 4
a1地址:0x7ffe4138e454
a2地址:0x7ffe4138e456

再看一个例子,把char和long放在一起,那么char自动补齐为8个字节,long是8个字节,加起来是16个字节。

typedef struct Test
{
    char a1;
    long a2;
}Test_T;
sizeof(T) = 16
a1地址:0x7fffb1c08ea0
a2地址:0x7fffb1c08ea8

通过示例证明以上结论是正确的。
以上示例都是两个变量,那再加一个变量呢?

typedef struct Test
{
    char a1;
    int a2;
    char a3;
}Test_T;
sizeof(T) = 12
a1地址:0x7fff4e115adc
a2地址:0x7fff4e115ae0
a3地址:0x7fff4e115ae4

依然证明结论是正确的,编译器为char a3补齐了4个字节的存储空间。
那再加一个char变量呢?

typedef struct Test
{
    char a1;
    int a2;
    char a3;
    char a4;
}Test_T;
sizeof(T) = 12
a1地址:0x7fffa28395ac
a2地址:0x7fffa28395b0
a3地址:0x7fffa28395b4
a4地址:0x7fffa28395b5

你会发现依然是12个字节,按照上面的结论不应该为char a4补齐4个字节的存储空间吗?答案是当a3和a4可以共用4个字节的存储空间的时候,就只会补齐1份4个字节的存储空间。再写一个示例验证下:

typedef struct Test
{
    char a1;
    int a2;
    char a3;
    char a4;
    char a5;
    char a6;
}Test_T;
sizeof(T) = 12
a1地址:0x7ffd38933d9c
a2地址:0x7ffd38933da0
a3地址:0x7ffd38933da4
a4地址:0x7ffd38933da5
a5地址:0x7ffd38933da6
a6地址:0x7ffd38933da7

会发现a3 a4 a5 a6共享一份1个字节的存储空间。

typedef struct Test
{
    char a1;
    int a2;
    char a3;
    char a4;
    char a5;
    char a6;
    char a7;
}Test_T;
sizeof(T) = 16
a1地址:0x7fffe2ebd7f0
a2地址:0x7fffe2ebd7f4
a3地址:0x7fffe2ebd7f8
a4地址:0x7fffe2ebd7f9
a5地址:0x7fffe2ebd7fa
a6地址:0x7fffe2ebd7fb
a7地址:0x7fffe2ebd7fc

会发现单独为char a7补齐了4个字节的存储空间。

总结

typedef struct Test
{
    char a1;
    int a2;
    char a3;
    short a4;
}Test_T;
sizeof(T) = 12
a1地址:0x7fff5d3488fc
a2地址:0x7fff5d348900
a3地址:0x7fff5d348904
a4地址:0x7fff5d348906

编译器会为char a1补齐4个字节的存储空间,会为char a3 、short a4补齐4个字节的存储空间。
所谓补齐,并非是变量真正占用,而是为程序多申请了内存空间。如下图所示


内存对齐.png

可以看到:a1只占用一个字节,为了内存对齐保留了三个空白字节;a3和a4加起来共3字节,为了内存对齐保留了1个空白字节。其实这就是空间换时间的一种思想运用。

参考

https://blog.csdn.net/zhengnianli/article/details/87390212

相关文章

  • sizeof与字节对齐

    参考 【面试题】sizeof引发的血案编译器与字节对齐c 语言字节对齐问题详解C/C++内存对齐内存存取粒度C和C...

  • 内存对齐

    在C语言柔性数组一文中,提到了内存对齐,于是想写篇文章总结总结内存对齐。 内存对齐 为什么需要内存对齐 计算机系统...

  • C语言 内存对齐

    引言 先看一个例子: 请问Test_T占几个字节?如果你的回复是 1 + 4 = 5,那就错了。我们看下程序运行的...

  • C面试-内存对齐

    参考: 【嵌入式时代】C语言面试题详解(第7节),不知道“内存对齐”的程序员是不合格的 转载自:C语言的内存对齐 ...

  • 解析C语言结构体对齐(内存对齐问题)

    解析C语言结构体对齐(内存对齐问题) C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。内容虽然很基础...

  • C语言中内存对其规则

    C语言中结构体内存对齐规则 对齐规则: 内存偏移为该数据类型的最小整数倍 总体占用内存为结构体中最大数据类型的整数...

  • sizeof(struct)

    在C语言中,结构体会以占用字节最长的变量为基准,做内存对齐。

  • golang 和 C++ 的内存对齐

    golang 和 C++的内存对齐,基本一致,记住规则和对应类型的 size 即可 内存对齐规则 有效对齐值是固定...

  • C语言12 字节对齐

    C语言12 字节对齐 我们发现,x跟y都是全局变量,但是它们的地址却不不是连续的. 字节对齐就是一个变量内存开始的...

  • 字节对齐与大端小端与内存区域划分

    字节对齐 C语言字节对齐C语言字节对齐/7213465 大端小端 字节序(大小端)详解从高低地址和高低位开始理解(...

网友评论

      本文标题:C语言 内存对齐

      本文链接:https://www.haomeiwen.com/subject/bovkyrtx.html