微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 硬件工程师文库 > 周立功教你学程序设计结构体:内存对齐和基本数据类型

周立功教你学程序设计结构体:内存对齐和基本数据类型

时间:08-01 来源:ZLG致远电子 点击:

第二章为程序设计技术,本文为2.2.1 内存对齐和2.2.2 基本数据类型。

我们知道,数组和指针是相同类型有序数据的集合,但很多时候需要将不同类型的数据捆绑在一起作为一个整体来对待,使程序设计更方便。在C语言中,这样的一组数据被称为结构体。

>>> 2.2.1 内存对齐

虽然所有的变量最后都会保存到特定地址的内存中,但相应的内存空间必须满足内存对齐的要求。主要出于两个方面的原因:

  • 平台原因:不是所有的硬件平台(特别是嵌入式系统中使用的低端微处理器)都能访问任意地址上的任意数据,某些硬件平台只能访问对齐的地址,否则会出现硬件异常。

  • 性能原因:如果数据存放在未对齐的内存空间中,则处理器访问变量时需要做两次内存访问,而对齐的内存访问仅需要一次访问。

在32位微处理器中,处理器访问内存都是按照32位进行的,即一次读取或写入都是4个字节,比如,地址0x0 ~ 0xF这16字节的内存,对于微处理器来说,不是将其看作16个单一字节,而是4个块,每块4个字节,详见图2.4。

图2.4  内存空间示意图

显然,只能从0x0、0x4、0x8、0xC等地址为4的整数倍的内存中一次取出4个字节,并不能从任意地址开始一次读取4个字节。假定将一个占用4字节的int类型数据存放到地址0开始的4字节内存中,其示意图详见图2.5。

图2.5  按内存对齐的方式存储int数据

由于int类型数据存放在块0中,因此CPU仅需一次内存访问即可完成对该数据的读取或写入。反之,如果将该int类型数据存放在地址1开始的4字节内存空间中,其示意图详见图2.6。

图2.6  按内存未对齐的方式存储int数据

此时,数据存放在块0和块1两个块中,若要完成对该数据的访问,必须经过两次内存访问,先通过访问块0得到该数据的3个字节,再通过访问块1得到该数据的1个字节,最后通过运算,将这几个字节合并为一个完整的int型数据。由此可见,若数据存储在未对齐的内存空间中,将大大降低CPU的效率。但在某些特定的微处理器中,它根本不愿意干这种事情,这种情况下,就出现系统异常,直接崩溃了。内存对齐的具体规则如下:

(1)结构体各个成员变量的内存空间的首地址必须是"对齐系数"和"变量实际长度"中较小者的整数倍。假设要求变量的内存空间按照4字节对齐,则内存空间的首地址必须是4的整数倍,满足条件的地址有0x0、0x4、0x8、0xC……

(2)对于结构体,在其各个数据成员都完成对齐后,结构体本身也需要对齐,即结构体占用的总大小应该为"对齐系数"和"最大数据成员长度" 中较小值的整数倍。

一般来说,对齐系数与微处理器的字长相同,比如,32位微处理器的对齐系数是4字节,变量的实际长度与其类型相关,计算类型长度的方法如下:

该程序的输出为:1、4、4、4、8。假定CPU为32位微处理器,对齐系数为4,结构体变量data的定义如下:

结构体的各个成员都是从结构体首地址(其由编译器保证必然满足内存对齐的要求,假定为0)开始计算,按照定义的顺序依次存放各个成员,详见表2.1。

表2.1  依次存放各个成员

实际存放位置使用[x,y]表示,x表示起始地址,y表示结束地址。如果x与y相等,则直接使用[x]表示。以成员b为例,其长度为2,小于对齐系数,因此按照2字节对齐,就要求其地址必须是2的倍数,地址0已经被成员a占用,则只能使用满足要求的邻近的内存空间[2,3]存放成员b。而空间[1]由于不满足存放成员b的要求,则只能被弃用。特别地,对于数组成员c,存放时不能将其看作一个整体,即长度为2的成员,应该分别看作两个成员c[0]和c[1]。由此可见,实际存放位置为[0,24],1、6、7、17、18、19部分内存空间被弃用。

当所有成员存放完毕后,则结构体本身也需要对齐,即结构体的大小也应该为对齐字节数的整数倍,对齐字节数取长度最长的成员和"对齐系数"的较小值。在这里,其长度最长的成员为double类型的成员d,其长度为8,大于对齐系数,因此结构体本身也要按照4字节对齐,其占用的空间大小必须是4的整数倍。虽然当前存放位置为[0,24],只占用了25个字节。由于必须满足4的整数倍,因此实际上结构体占用的空间是28个字节,即[0,27]。验证结构体占用空间大小的方法如下:

虽然所有成员的总长度为19个字节,但结构体实际占用了28个字节,多余的9个字节空间为内存对齐弃用的空间,即1、6、7、17、18、19、25、26、27,分为4个段:[1],[6,7],[17,19],[25,27]。查看表2.1可知,这些浪费空

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top