内存对齐-C语言struct内存占用问题
转1个写的比较全面的.
http://hubingforever.blog.163.com/blog/static/17104057920122256134681/
本文编辑整理自:
http://hi.baidu.com/pine515/blog/item/28f41f496042e8ee83025c4e.html
http://blog.sina.com.cn/s/blog_4913c1f301000bip.html
一、 ANSI C标准中并没有规定,相邻声明的变量在内存中一定要相邻。
,,。而且在上述的三条中,第2条里,offset必须是成员 大小的整数倍,如果这个成员大小小于等于4则按照上述准则进行,但是如果大于4了,则结构体每个成员相对于结构体首地址的偏移量(offset)只能按照 是4的整数倍来进行判断是否添加填充。
譬如:
) ) ,如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准,即是说,结构体成员的偏移量应该取二者的最小值,公式如下:
offsetof( item ) = min( n, sizeof( item ) )
注意:如果#pragma pack (n)中指定的n大于结构体中最大成员的size,则其不起作用,结构体仍然按照size最大的成员进行对界。
VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。
VC 中提供了#pragma pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏 移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条 件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。
下面举例说明其用法。
#pragma pack(push) //保存对齐状态
#pragma pack(4)//设定为4字节对齐
struct test
{
char m1;
double m4;
int m3;
};
#pragma pack(pop)//恢复对齐状态
以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满足我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始 为 m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大于n),m4占用8个字节。接 着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用4个字节。这时已经为所有成员变量分配了空间,共分配了16个字节,满足为n的倍数。如 果把上面的#pragma pack(4)改为#pragma pack(16),那么我们可以得到结构的大小为24。
四、“空结构体”(不含数据成员)的大小不为0,而是1。
试想一个“不占空间”的变量如何被取地址、两个不同的“空结构体”变量又如何得以区分呢?于是,“空结构体”变量也得被存储,这样编译器也就只能为其分配一个字节的空间用于占位了。
如下:
struct S { };
sizeof( S ); // 结果为1
五、含位域结构体的sizeof
位域成员不能单独被取sizeof值,我们这里要讨论的是含有位域的结构体的sizeof,只是考虑到其特殊性而将其专门列了出来。
C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在
七天、补充
有朋友对上面的内容提出了一下质疑:
质疑1
2012-01-03 01:08 | 回复
个人觉得可能是新版本的编译器已经把这部分的规则统一了。
内存对齐-C语言struct内存占用问题的更多相关文章
- 什么是内存对齐,go中内存对齐分析
内存对齐 什么是内存对齐 为什么需要内存对齐 减少次数 保障原子性 对齐系数 对齐规则 总结 参考 内存对齐 什么是内存对齐 弄明白什么是内存对齐的时候,先来看一个demo type s struct ...
- JVM内存管理------JAVA语言的内存管理概述
引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...
- Net的struct的内存对齐问题
很少有人谈起struct的内存对齐问题, 就是在很多C#书中, 也很少提及. 但在实际应用中, 如果不注意内存对齐, struct比较大的话, 则会浪费一定的内存. 先从一个实例看起. publ ...
- C语言内存对齐
转:http://blog.csdn.net/embeddedman/article/details/7429976 首先由一个程序引入话题: 1 //环境:vc6 + windows sp2 2 ...
- 从硬件到语言,详解C++的内存对齐(memory alignment)
转载请保留以下声明 作者:赵宗晟 出处:https://www.cnblogs.com/zhao-zongsheng/p/9099603.html 很多写C/C++的人都知道“内存对齐”的概念以及规则 ...
- 从硬件到语言,详解C++的内存对齐(memory alignment)(一)
作者:赵宗晟 出处:https://www.cnblogs.com/zhao-zongsheng/p/9099603.html 很多写C/C++的人都知道“内存对齐”的概念以及规则,但不一定对他有很深 ...
- C\C++ 内存对齐现象
前几天一个在自学C语言的小伙伴问了我个问题,C语言结构体储存所占空间为啥和自己预测的不一样.看一下下面这一段代码: struct node{ int num; char ch; }a; printf( ...
- C/C++中的内存对齐 C/C++中的内存对齐
一.什么是内存对齐.为什么需要内存对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址 ...
- NumPy-快速处理数据--ndarray对象--多维数组的存取、结构体数组存取、内存对齐、Numpy内存结构
本文摘自<用Python做科学计算>,版权归原作者所有. 上一篇讲到:NumPy-快速处理数据--ndarray对象--数组的创建和存取 接下来接着介绍多维数组的存取.结构体数组存取.内存 ...
随机推荐
- 《Linux shell编程中 diff与vimdif的使用》RHEL6
linux比较2个文件的区别有两个命令: (1)diff (2)vimdiff cp /etc/grub.conf hello 在hello文件的末尾添加zhangsan 使用diff比较2个文件的区 ...
- FPGA/CPLD设计思想与技巧
本文讨论的四种常用FPGA/CPLD设计思想与技巧:乒乓操作.串并转换.流水线操作.数据接口同步化,都是FPGA/CPLD逻辑设计的内在规律的体现,合理地采用这些设计思想能在FPGA/CPLD设计工作 ...
- HTML5+CSS3+JQuery打造自定义视频播放器
来源:http://www.html5china.com/HTML5features/video/201109206_1994.html 简介HTML5的<video>标签已经被目前大多数 ...
- javascript代码复用--继承
由于javascript没有类的概念,因此无法通过接口继承,只能通过实现继承.实现继承是继承实际的方法,javascript中主要是依靠原型链要实现. 原型链继承 原型链继承是基本的继承模式,其本质是 ...
- eclipse 安装插件不生效
操作: 下载了一个插件,插件中只有一个jar包,解压放到plugins目录,插件没生效. 解决方法: 把jar包直接扔到dropins目录下,并且删除eclipse\configuration\org ...
- posix 消息队列
注意 在涉及到posix消息的函数时, gcc 编译时要加-lrt参数, 如 gcc -lrt unpipc.c mqpack.c send.c -o send gcc -lrt unpipc.c m ...
- C# 命名参数【转】
命名参数(Named Arguments)就是说在调用函数时可以通过指定参数名称的方式来调用参数.它最大的好处就是方便调用参数时按调用者的需要来排列顺序,而不必死守函数声明时的顺序(相对于“位置参数” ...
- usb wifi driver run in ubuntu support 360/xiaodu and with 3.13.0-32-generic
(为了实现usb-wifi用在linux系统上,需求解决方案,过程记录和如何实现) 重点解决3.13.0-32-generic内核编译 mt7601 usb wifi 驱动问题. 1:首先下载MT76 ...
- matlab实现共轭梯度法、多元牛顿法、broyden方法
共轭梯度法: function [ x, r, k ] = CorGrant( x0, A, b ) x = x0; r = b - A * x0; d = r; X = ones(length(x) ...
- iOS 进阶 第三天(0326)
0326 Xib:描述软件界面,轻量级,一般用来描述局部界面 Xib的获取,如下图所示: xib在我们开发的时候叫xib,但如果运行在我们手机里会生成nib.所以xib和nib两种方法来访问xib