更多课程 选择中心

C/C++培训
达内IT学院

400-111-8989

理一理C语言字节对齐的那些事

  • 发布:C++培训
  • 来源:C++资讯
  • 时间:2020-08-03 14:52

字节对齐是我们初学C语言就会接触到的一个概念,但是到底什么是字节对齐?对齐准则又是什么?为什么要字节对齐呢?字节对齐对我们编程有什么启示?本文将简单理一理字节对齐的那些事。

什么是字节对齐

计算机中内存大小的基本单位是字节(byte),理论上来讲,可以从任意地址访问某种基本数据类型,但是实际上,计算机并非逐字节大小读写内存,而是以2,4,或8的 倍数的字节块来读写内存,如此一来就会对基本数据类型的合法地址作出一些限制,即它的地址必须是2,4或8的倍数。那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。

对齐准则是什么:

总的来说,字节对齐有以下准则:

结构体变量的首地址能够被其最大基本类型成员字节数大小所整除。

结构体每个成员相对结构体首地址的偏移都是成员大小的整数倍,如不满足,对前一个成员填充字节以满足。

结构体的总大小为结构体对最大成员大小的整数倍,如不满足,最后填充字节以满足。

我们通过一个小例子来说明是如何对齐的。

考虑下面的程序:

#include<stdio.h>

#include<stdint.h>

struct test

{

int a;

char b;

int c;

short d;

};

int main(int argc,char *argv)

{

/*在32位和64位的机器上,size_t的大小不同*/

printf("the size of struct test is %zu

",sizeof(struct test));

return 0;

}

编译成32位程序并运行(默认四字节自然对齐),可以看到,结构体test 的大小为16字节,而不是11字节(a占4字节,b占1字节,c占4字节,d占2字节)

#64位机器上编译32位程序可能需要安装一个库

#sudo apt-get install gcc-multilib

gcc -m32 -o testByteAlign testByteAlign.c #编译程序

chmod +x testByteAlign #赋执行权限

./testByteAlign #运行

the size of struct test is 16

实际上,结构体test的成员在内存中可能是像下面这样分布的(数值为偏移量)

未对齐时:

0~3 4 5~9 10~11
a b c d

对齐时:

0~3 4 5~7 8~11 12~13 14~15
a b 填充内容 c d 填充内容

从上面可以看出,c的偏移为5,不满足对齐要求(它的偏移量应该能够被sizeof(int)大小整除),因此在b后面填充了3个字节,使得c的偏移为8。在b后面填充后,d已经满足对齐要求了,为什么最后还要填充字节呢?或者说,为什么需要满足第三条准则呢?

考虑下面的声明

struct teArray[2];

我们不难知道,teArray[0]的d如果不填充字节,那么teArray[1]的a偏移为14,不满足对齐要求,因此d后面也需要填充字节。

为什么要字节对齐

无论数据是否对齐,大多数计算机还是能够正确工作,而且从前面可以看到,结构体test本来只需要11字节的空间,最后却占用了16字节,很明显浪费了空间,那么为什么还要进行字节对齐呢?最重要的考虑是提高内存系统性能

前面我们也说到,计算机每次读写一个字节块,例如,假设计算机总是从内存中取8个字节,如果一个double数据的地址对齐成8的倍数,那么一个内存操作就可以读或者写,但是如果这个double数据的地址没有对齐,数据就可能被放在两个8字节块中,那么我们可能需要执行两次内存访问,才能读写完成。显然在这样的情况下,是低效的。所以需要字节对齐来提高内存系统性能。

在有些处理器中,如果需要未对齐的数据,可能不能够正确工作甚至crash,这里我们不多讨论。

当你还在担心能否就业时,达内学员提前被企业录取;当你转辗于各大招聘会时,达内学员收到了高薪offer;当你在各大招聘网站投递简历时,达内学员中有人一毕业进入五百强名企。所以选择很重要。找C++培训班,选达内就对了。

版权声明:转载文章来自公开网络,版权归作者本人所有,推送文章除非无法确认,我们都会注明作者和来源。如果出处有误或侵犯到原作者权益,请与我们联系删除或授权事宜。

预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:C程序为什么要初始化?
下一篇:收藏!5个最常用的C++经典算法代码

C语言宏定义的几种使用方法

C与C++内存管理避坑指南

C/C++代码规范注释有哪些讲究?

C语言中,全局变量滥用的后果竟如此严重?

  • 扫码领取资料

    回复关键字:视频资料

    免费领取 达内课程视频学习资料

  • 搜索抖音号

    搜索抖音号:1821685962

    免费领取达内课程视频学习资料

Copyright © 2021 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省