美文网首页底层原理
C面试-内存对齐

C面试-内存对齐

作者: 路漫漫其修远兮Wzt | 来源:发表于2019-03-06 09:30 被阅读0次

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

转载自:C语言的内存对齐

例子

从一个例子开始, 象下面这样定义的结构体占几个字节?

typedefstruct{

    char a;
    int i;
} Sample;

char占1个字节,int占4个字节,答案是5个字节? 错了。如果用 gcc 编译,sizeof(Sample) 的结果是8个字节。
这是怎么回事?进一步观察,Sample第0个字节是a, 而Sample的成员int i从第4个字节开始。 这是编译器为了内存对齐所做的优化。

什么是内存对齐

比如数据总线有32位,它访存只能4个字节4个字节地进行。 0-3,4-7,8-11,12-15,…… 即使我们需要的数据只占一个字节,也是一次读取4个字节。 一个字节的数据不管地址是什么,都能通过一次访存读取出来。 而如果要读取的数据是一个字节以上,比如两个字节, 如果该数据的内存地址是0x03,则需要两次才能读取该数据, 第一次读0x00-0x03,第二次读0x04-0x07。 这个数据就跨越了访存边界。

而相对CPU的运算来说,访存是非常慢的,所以要尽量减少访存次数。 为了减少跨越访存边界的数据引起的访存开销, 所以编译器会进行内存对齐,即把变量的地址做一些偏移, 目的是一次访存就读出数据,不然的话也要以尽可能少地访存次数读出数据。

如上一个例子中那样,整型成员i的地址做4个字节的偏移, 而Sample对象的地址也会做4字节边界的对齐, 这样i的地址始终是4的倍数,从而使得i不跨越访存边界, 能一次读出它的值。

尽可能少的内存占用

typedefstruct{
    char a;
    char b;
    int i;
} Sample1;

Sample1占多少空间呢?仍然是8个字节。 a在第0个字节,b在第1个字节,i占4-7字节。 这是内存对齐的原则,占用尽量少的内存。 如果在b之后,还有char类型的成员c和d,同样是占8个字节。 a,b,c,d在0-3字节。

数据成员顺序影响内存的占用

typedefstruct{
    char a;
    int i;
    char b;
} Sample2;

Sample2的数据成员和Sample1的数据成员相同,只是顺序不一样, 是否占用一样多的内存呢?答案是不一样。 Sample1占用8字节,而Sample2占用12个字节!

这是为什么呢?32位机器上,访存单元是4字节。 对于多于4字节的数据,以4字节为单位做内存对齐的。 所以对于上述的结构体数据的地址分配,都是4的倍数。 对于结构体内部,以数据成员的最大长度为对齐单位。 如果数据成员的长度超过4字节,仍然以4字节为对齐单位,这是因为访存单元就是4字节。 在Sample2的定义中,因为int是4字节,所以以4字节为内存对齐的单位。

在Sample2中,对于a来说,只占一个字节,无所谓对不对齐,它在0字节。 i是int类型,要对齐,在4-7字节。 b在8字节,虽然它只占一个字节,但因为结构体内是以4字节为单位对齐的, 所以编译器一下多分配出4个字节,所以共占了12个字节。

以上的Sample1和Sample2的例子说明,即使是同样的结构体,如果数据成员的顺序不同,所占的内存空间可能是不同的。

总结

如果我们对内存对齐有概念,在定义结构体的时候就会留心数据成员的顺序,从而能 减少程序的内存占用。
以前我使用变量存放较小的整数时,为了减小内存占用,往往把变量定义成char型, 但现在明白了,因为编译器的内存对齐,节省内存的效果并没有那么理想。

如果内存真的很受限,可以用 #pragma pack(1) 告诉编译器关闭内存对齐。

相关文章

  • sizeof与字节对齐

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

  • C面试-内存对齐

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

  • iOS 开发 内存对齐(练习)

    目录 内存对齐规则 对齐系数 面试题演练 一、内存对齐规则 (关于面试题中结构体内存对齐计算总结) 1.1、数据成...

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

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

  • 内存对齐

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

  • C/C++内存对齐

    在面试或工作中,经常会遇到内存对齐的问题。这里结合我的理解谈一谈对内存对齐的理解。 1. 为什么要内存对齐,不对齐...

  • iOS底层之内存对齐算法解析

    目前但凡一个iOS岗面试都会问个内存对齐问题,那么什么是字节对齐?成员变量对齐和对象内存对齐有什么区别?今天我来为...

  • golang 和 C++ 的内存对齐

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

  • [Daozy][C 语言入门课程]第24课 常见面试题分析

    [Daozy][C 语言入门课程]第24课 常见面试题分析 当前课程对应视频:待实现 题目1:内存对齐 实例代码 ...

  • c++内存对齐

    1、为什么要进行内存对齐呢? 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台...

网友评论

    本文标题:C面试-内存对齐

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