文档章节

关于结构体的内存对齐

zhangyujsj
 zhangyujsj
发布于 2014/10/05 00:43
字数 771
阅读 6
收藏 0

作者:冯老师,华清远见嵌入式学院讲师。

内存是以字节为单位编号,但一些硬件平台对某些特定类型的数据只能从某些特定地址开始,比如从偶地址开始。若不按照适合其平台的要求对数据存放进行对齐,会影响到效率。因此,在内存中,各类型的数据是按照一定的规则在内存中存放的,这就是本文要研究的对齐问题。

本文以gcc version 4.4.5,32位x86环境为例,来分析结构体中各成员如何进行对齐。

我们要注意两个方面:1)结构体成员变量对存放的起始地址有要求。2)结构体变量占用的总长度也有要求。

结构体对齐规则如下:

数据成员最终的存放地址:对齐在自身类型长度和pragma pack(value)指定值中较小的值上。

结构体的总长度:对齐在成员类型长度最大的值和pragma pack(value)指定值中较小的值上。

所谓“对齐在N上”,指定是“存放起始地址%N=0”

看下面几个例子:

例1:

分析:此程序的测试环境,相当于pragma pack(4),

a 成员的起始地址是0xbfe8ff18,

char类型长度1,pragma pack(4),取小的1, 0xbfe8ff18%1=0,符合规则。

b成员,short类型长度2,pragma pack(4),取小的2,若存在地址0xbfe8ff19,则0xbfe8ff19%2余数为1,不是0,所以只能空出一个字节,在0xbfe8ff1a地址存放。

c成员,int类型长度4,pragma pack(4),取小的4,若存在地址0xbfe8ff1a+2,即0xbfe8ff1c处,则0xbfe8ff1c%4余数为0,符合规则。

这样整个结构体,占用了内存的0xbfe8ff18~0xbfe8ff1f, 共8个字节。结构体的总长度是要求“对齐在成员类型长度最大的值和pragma pack(value)指定值中较小的值上。”这里是要求能被4除尽,8符合要求,所以sizeof(struct F)是8.

例2:

a成员的起始地址是0xbfe8ff18,

char类型长度1,pragma pack(4),取小的1, 0xbfbb41a8%1=0。

b成员,int类型长度4,pragma pack(2),取小的2,若存在地址0xbfbb41a9,则0xbfbb41a9%2余数为1,不是0,所以只能空出一个字节,在0xbfbb41aa地址存放。

c成员,short类型长度2,pragma pack(2),取小的2,若存在地址0xbfbb41aa +4,即0xbfbb41ae处,则0xbfbb41ae %4余数为0,符合规则。这样整个结构体,占用了内存的0xbfbb41a8~0xbfbb41af, 共8个字节。结构体的总长度是要求“对齐在成员类型长度最大的值和pragma pack(value)指定值中较小的值上。”这里是要求能被2除尽,8符合要求,所以sizeof(struct F)是8.

例3:

具体的分析,不再重复,读者可以和上面的例子做个比较,有了pragma pack(4)后,结构体的总长度,为12,不再是8。

本文转载自:http://www.embedu.org/Column/Column475.htm

zhangyujsj
粉丝 24
博文 358
码字总数 224241
作品 0
广州
私信 提问
sizeof运算符详解及对象大小

sizeof 是运算符,而不是函数。虽然我们习惯sizeof(...),但( )并不是必需的,它只是表示优先级。我们把sizeof后面的目标叫对象或者操作数。本文约定就叫sizeof对象。 当sizeof 的对象是表达...

yintao
2014/05/13
0
0
关于c语言内存地址对齐的一点思考

前言 相信大家对内存对齐这个概念一定都比较熟悉,本文将介绍,如何利用内存对齐这一特性来做一些有意思的探索。 至于为什么要使用内存对齐,这是一个比较复杂的问题,简单来说就是提高cpu a...

算法与编程之美
2013/10/09
0
40
C语言中结构体在函数中的应用

一、结构体与函数参数 结构体作函数参数可分为传值与传指针。 1.传值时结构体参数会被拷贝一份,在函数体内修改结构体参数成员的值实际上是修改调用参数的一个临时拷贝的成员的值,这不会影...

学习环境
2015/09/22
104
0
【结构体】关于结构体,枚举,联合,位段的一些知识

** 1.结构体类型创建 结构体市一些值的集合,这些值成为成员变量。 结构体的每个成员可以是不同类型的变量 结构体的成员可以是标量,数组,指针甚至是其他的结构体 不同的结构体之间不允许赋...

qregi
2017/12/13
0
0
Go语言之 unsafe 包之内存布局

unsafe,顾名思义,是不安全的,Go定义这个包名也是这个意思,让我们尽可能的不要使用它,如果你使用它,看到了这个名字,也会想到尽可能的不要使用它,或者更小心的使用它。 虽然这个包不安...

baby神
2018/07/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Netty源码学习(一)--导入IDEA并编译

1.从github下载最新的Netty稳定版本源码 2.解压源码文件夹 3.导入IDEA 4.跳过checkstyle和xml validate <plugin> <artifactId>maven-checkstyle-plugin</artifactId> <version>2.12.......

湖之风情
8分钟前
0
0
电商网站用户端FE

需求拆分原则 1、单个迭代不宜太大 2、需求可交付,能够形成功能闭环 3、有成本意识,遵循二八原则 4、有预期的价值体现 提炼核心需求 用户端:商品、购物车、下单、支付、订单、用户 后台管...

星闪海洋
20分钟前
0
0
Awesome Blockchain 区块链技术导航

区块链技术导航:收集整理最全面最优质的区块链(BlockChain)技术开发相关资源。 以后找不到文档资料的时候去导航站看看。 先亮个像,我长这样: 导航站内容 区块链开发所涉及的资源: 如 项目...

Tiny熊
23分钟前
0
0
聊聊我的第一篇10万+,同时反驳某些评论

元旦的时候,我立了一个Flag,今年要写一篇10万+,现在目标算是完成一半了。 终于有了一篇10万+ 知乎后台显示我的回答《如何衡量一个人的 JavaScript 水平?》的阅读量已经超过了10万,具体截...

Fundebug
30分钟前
0
0
ping的用法

ping的用法: -t ping指定的主机,直到停止。若要查看统计信息并继续操作-请键入 Control-Break; 若要停止-请键入Control-C。 -a 将地址解析成主机名。 -n count 要发送的回显请求数。 -l s...

WinkJie
31分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部