当前位置:  编程技术>c/c++/嵌入式

C/C++数据对齐详细解析

    来源: 互联网  发布时间:2014-10-21

    本文导语:  Data Alignment 关于数据对齐问题,现在多多少少有了一些接触,简单地说下自己的看法。 1、对齐的背景 大端和小端的问题有必要在这里介绍一下,计算机里面每个地址单元对应着一个字节,一个字节为8bit,对于位数大于8位的...

Data Alignment

关于数据对齐问题,现在多多少少有了一些接触,简单地说下自己的看法。

1、对齐的背景

大端和小端的问题有必要在这里介绍一下,计算机里面每个地址单元对应着一个字节,一个字节为8bit,对于位数大于8位的处理器来说,寄存器的宽度是大于一个字节的,例如16bit的short型变量x,在内存中的地址是0x0010,x的值为0x1122,0x11为高字节,0x22为低字节,常用的X86结构是小端模式,很多ARM,DSP都是小端模式,而KEIL C51则为大端模式。内存空间是按照byte进行划分的,理论上对任何类型的变量的访问可以从任何地址开始,但实际上访问特定变量的时候经常在特定的内存地址访问,这就需要各类型的数据按照一定的规则在空间上排列,而不是顺序排列,这就是对齐。

2、对齐的原因

不同硬件平台对存储空间的处理是有很大不同的,一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况, 但是最常见的是如果不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为 32位)如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低 字节进行拼凑才能得到该int数据。显然在读取效率上下降很多。这也是空间和时间的博弈。

3、对齐的实现

通常我们在写代码的时候是不需要考虑对齐的影响的,都是依赖编译器来为我们选择适合的对齐策略,我们也可以通过传递给编译器预编译指令来指定数据对齐的方法。

以struct数据结构的sizeof方法为例,环境是Mac OS X 64位内核,结构体的定义如下:

struct A {
int a;
char b;
short c;
};

struct B {
char b;
int a;
short c;
};

#pragma pack(2)
struct C {
char b;
int a;
short c;
};
#pragma pack()

#pragma pack(1)
struct D {
char b;
int a;
short c;
};
#pragma pack()

int main(int argc, char** argv)
{
printf("size of struct A : %lu n", sizeof(struct A));
printf("size of struct B : %lu n", sizeof(struct B));
printf("size of struct C : %lu n", sizeof(struct C));
printf("size of struct D : %lu n", sizeof(struct D));
return 0;
}

输出:
size of struct A : 8
size of struct B : 12
size of struct C : 8
size of struct D : 7

结构体中包含了4字节长度的int一个,1字节长度的char一个以及2字节长度的short一个。加起来所用到的内存空间为7个字节,但实际使用sizeof时发现,结构体之间占用的内存是不一样的。

关于对齐有几个需要说明的:
(1)数据类型自身的对齐值:基本数据类型的自身对齐值,char类型为1,short类型为2,int,float,double为4;

(2)指定对齐值:#pragma pack(value)时的指定对齐值value;

(3)结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值;

(4)数据成员、结构体和类的有效对齐值:自身对齐值或指定对齐值中较小值。

对于一个具体的数据结构的成员和其自身的对齐方式,有效对齐值N将最终决定数据存放地址的方式的值,对齐在N上就意味着数据“存放的起始地址%N=0”,

下面来针对上面的例子进行分析:
struct B {
char b;
int a;
short c;
};

假设B从地址空间0x0000开始,默认的对齐值是4(这里有个问题想请教大家,我的是64位的内核,但是测试我的默认对齐方式为4),第一个成员变量b的自身对齐值为1,比默认值小所以有效对齐值为1,存放地址0x0000%1=0,第二个成员变量a,自身对齐值为4,存放的起始地址为0x0004到0x0007这个4个连续的字节空间中,0x0004%4=0,第三个变量c,自身对齐值为2,存放的起始地址为0x0008到0x0009,地址同样符合要求。结构体B的自身对齐值为变量中的最大对齐值(b)4,(10+2)%4=0,所以0x000A到0x000B也是被结构体B占用。
内存中的示意图:
b - - -
a a a a
c c

#pragma pack(2)
struct C {
char b;
int a;
short c;
};
#pragma pack()

第一个变量b的自身对齐值为1,指定对齐值为2,有效对齐值为1,b存放在0x0000,a的自身对齐值为4,大于指定对齐值,所有有效的对齐值为2,a占有的字节为0x0002、0x0003、0x0004、0x0005四个连续字节中,c的自身对齐值为2,所以有效对齐值也是2,顺序存放在0x0006、0x0007。结构体C的自身对齐值为4,所以有效对齐值为2,8%2=0。
内存中的示意图:
b -
a a
a a
c c

其实想到内存中的示意图一切都会简单很多。


    
 
 

您可能感兴趣的文章:

  • 请教:如何判别数据帧的CRC错误?对齐错?
  • 浅析内存对齐与ANSI C中struct型数据的内存布局
  • php通过pack和unpack函数实现对二进制数据封装及解析
  • 请教串口通信中用超级终端配置时数据解析
  • Java结构化数据解析包 Lycia
  • 磁道数据解析器 Magnetic Track Parser
  • PHP的XML和JSON数据解析和缓存包 coreylib
  • 解析MYSQL 数据库导入SQL 文件出现乱码的问题
  • 地图数据解析器 Osmosis
  • 解析mysql中如何获得数据库的大小
  • 解析如何用指针实现整型数据的加法
  • 解析mysql数据库还原错误:(mysql Error Code: 1005 errno 121)
  • 解析如何使用Zend Framework 连接数据库
  • php解析json数据实例
  • 关于解析ssh协议加解密数据的问题?
  • 请问如何解析这个文本啊?然后进行插入到数据库中?
  • 怎样让我的程序能像mysql一样运行后有一个mysql>的提示符等待用户输入并解析用户输入的数据然后执行操作?
  • 深入解析C语言中常数的数据类型
  • linux下用libxml2解析包含中文数据的xml时出错
  • 一个删选数据的例子,使用GROUP、DISTINCT实例解析
  • 解析Android中string-array数据源的简单使用
  • python解析发往本机的数据包示例 (解析数据包)
  • 深入解析Linux下MySQL数据库的备份与还原
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间javax.print类docflavor的类成员方法:服务格式化打印数据定义及介绍
  • 如何监控数据库的数据,如果数据库数据更改,就通知Server
  • <<大话数据结构>>中冒泡排序算法改进
  • 如何从数据库中或文本文件中提取数据到另一个数据库中?
  • java命名空间javax.print类docflavor的类成员方法:客户端格式化打印数据定义及介绍
  • 用JDBC连接Oracle数据库时,如何向数据库中写日期型数据(格式)?谢了!
  • 基于Key-Value的NOSQL数据库Redis的数据结构及常用相关命令介绍
  • linux下用libpcap库函数抓包,如何判断捕获的数据包是IP数据包还是非IP数据包,顺便说一下、捕获的数据包除了IP数据包之外,还有那些种类,非常感谢!!!
  • c#多线程更新窗口(winform)GUI的数据
  • 建立一个ftp数据连接并传送或接受完毕一些数据后,能否不关闭此数据连接,下次接着用?
  • 基于Hadoop的数据挖掘框架
  • 我从JSP页将数据插入到oracle数据库中,为何汉字插入后数据库中显示为乱码呢?
  • sharepoint 2010中item.Update()和item.SystemUpdate 修改数据版本问题解决
  • 串口应用程序,当对方发送大量的数据时,本方的数据无法发出。对方停止发送,本方的数据仍然无法发出。不知道是什么原因。
  • Linux c++库boost unordered_set数据插入及查找代码举例
  • 公司要给客户做报表,从数据库返回数据,他们死活要返回的格式为Excel格式,请问我怎样才能把数据库返回的数据存为Excel的格式?
  • 文档数据库mongodb与列式数据库hbase详细比较
  • 数据在页面写不进数据库,也不可以从数据库中读出是什么原因?
  • SQL Server 2008如何进行数据库分离和附加详细介绍
  • mysql 本地数据库如何从远程数据库导数据
  • nosql数据库levedb介绍及levedb最新版1.18下载安装
  • 散分:Jbuilder6开发数据库应用请问你们都用什么数据库? 免费的数据库有那些?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3