0
点赞
收藏
分享

微信扫一扫

C/C++里地址对齐理解

非常帅气的昵称吧 2022-03-13 阅读 85

本文主要讲述一下C/C++里变量地址的对齐,不仅仅是C/C++,其它语言也是一样。这个是计算机系统要求的。


一 为什么要对齐

在硬件设计上,为了提高效率,CPU从RAM里拿数据不是一个字节一个字节去读的,而是一次读取多个字节,例如如8个。如果代码里的变量地址不对齐(不是8的倍数),那么就会降低CPU的效率。

例如一个长整型是8个字节,如果其起始地址不是8的倍数,如下图这样,绿色是长整型数据在ram里的排布,
在这里插入图片描述
那么CPU就需要取2次才能拿到这个长整型数据的完整值,第一次从位置0取8个字节,第二次从位置8取8个字节;如果其地址是8的倍数,那么就只需要取一次了。

我们在编写程序时,可能会有大量的变量,如果不对齐,叠加起来就会大幅降低CPU的效率。


二 如何保证对齐

编译器在把源码变成汇编代码时,会在代码中放入命令来指示需要的对齐字节数,如下这种,

.align 4

这是一个对齐伪指令,表示要求4字节对齐,也可以改成2,8,16等。这条指令后面的内存变量必须从下一个能被4整除的地址开始分配。如果下一个地址不能被4整除,汇编程序将空出若干个字节,直到下一个地址能被4整除为止。

只要第一个变量的起始地址对齐,那么后续的其它变量只要保证自身所占内存空间是4的倍数,那么它们的起始地址就都会自动对齐。


三 结构体对齐

这里讲一下结构体是如何对齐的,

struct A
{
    int d1;
    char d2;
    int d3;
};

为了保证结构体内每个元素的起始地址都是4字节对齐的,那么就会按照如下方式排布,
在这里插入图片描述
这样这个结构体的实际长度是12个字节,d2后面会补充3个padding字节,这是通过牺牲一定的空间来实现对齐,提高效率。

如果结构体的定义如下,

struct A
{
    int d1;
    int d2;
    char d3;
};

那么d3后面还需要补充3个padding字节吗?因为d3的起始地址已经是4字节对齐的。答案是需要,因为有可能定义struct A的数组,

struct A a[10];

数组的空间是连续的,如果d3后面不补充3个padding字节,那么后面元素的起始地址就不是4字节对齐了。

所以这个结构体内存分布如下,仍然占12个字节。
在这里插入图片描述

举报

相关推荐

0 条评论