内存对齐 结构体内存大小大小为什么是64?求指导

2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
本帖子已过去太久远了,不再提供回复功能。求问几个结构的内存字节对齐的问题【c++吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:298,118贴子:
求问几个结构的内存字节对齐的问题收藏
#pragma pack(n)如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数 以保证边界对齐
为什么这样规定可以保证边界对齐还有复杂类型(结构)默认对齐参数是其中最长成员的对齐参数
这样当成员是复杂类型时保证占用内存最小 为什么这样规定可以保证占用内存最小不太理解两个规定的意义 这应该算 数学问题?
博为峰作为良心上市企业,提供免费试学,零元入学服务,签订就业协议,保障薪水8K+.博为峰拒绝灌输式填鸭教学,让每个c++都可以独当一面,成为大牛!
虽然不认识,但我是来膜拜宫吧前辈的。。。
.... 求解答一楼的问题
我是不是应该过几年再来挖这个坟
前辈,你找度娘、谷哥来问一下不就可以了嘛?
看到前辈买萌,亚历山大。拖度娘嘴里就出来了,您看是不是?
... 为啥叫我前辈
我明明是新人
宫吧来的都是我前辈。
我才是没存在感的新人。
传智c++,不断超越自己,打造更深更全面的课程,大牛带你赢高薪c++,讲师高超的授课技巧和精品课程,成就了一批又一批业界精英!
咱好久都不去了...
首页没几个认识的 到处都是水贴 没意思
说得好,Me也好久没去了,去了也就顶顶Saber楼。
一直没太明白结构体是怎么对齐的,我猜猜:1、可能就是指如果n超过 占用空间最大的成员的大小,就按 占用空间最大的成员的大小 对齐,这时 占用空间最大的成员的大小就是整个结构体的最大单个成员边界2、总感觉是访问速度最快而非总大小最小,会不会是说错了求高手
...对啊n和最大成员占用的空间 两者取小...
如果n大于最大成员占用的空间 占用的总空间必须是最大成员占用空间的整倍数目的是为了访问方便快捷- - 可是我1l的问题是
“n和最大成员占用的空间 两者取小...
如果n大于最大成员占用的空间 占用的总空间必须是最大成员占用空间的整倍数
”这样规定的意义何在
会不会是这样:struct B//对齐从而提升a或c的访问速度?
提高a或c的访问速度? 怎么说
..恩 麻烦说详细一点 没明白..
对齐的概念先要弄清楚,你的结构体所占的空间不是n和最大成员空间二者取小,这里的二者取小是指计算对齐空间的地址时使用的余数是二者取小。对齐的目的是为了防止破裂读取影响计算机的运算效率,而所谓的对齐操作是对空间的起始地址进行对齐。你所谓的占最大空间的整数倍仅仅是在内部所有变量都计算完之后进行的计算。举个例子:比如我有一个结构体(使用vc2008)struct A{
};double + char + int 的总大小是8 + 1 + 4 = 13 而sizeof(A)= 16但是如果我调换下变量的位置,总大小又会发生变化:struct A{
}; 这个时候sizeof(A) = 24 变得更大了所以结构体的大小会随着你变量的位置不同而发生变化为了说明这个问题和对齐操作,我们需要计算一下:首先,char 默认对齐大小是1, double为8, int为4,并且假设结构体起始地址为0第一种情况:结构体A的对齐值为其中最大的变量的对齐值,即为double的 8然后计算结构体内部变量的对齐地址:第一个变量为c,对齐值为8, 由于起始地址为0,0 % 8 = 0 所以c的存放位置为0~7这几块第二个变量为b,对齐值为1,由于起始地址为8, 8 % 1 = 0 所以b的存放位置为8这一块第三个变量为c,对齐值为4,由于起始地址为9, 9 % 4 != 0 所以需要存放位置需要移后,我们发现 12 % 4 = 0 ,所以c的存放位置为12~15这几块最后,结构体的总大小需要 % 8 = 0 由于16 % 8 = 0 ,所以总大小为16 第二种情况 :结构体A的对齐值为其中最大的变量的对齐值,即为double的 8然后计算结构体内部变量的对齐地址:第一个变量为b,对齐值为1, 由于起始地址为0,0 % 1 = 0 所以c的存放位置为0这一块第二个变量为c,对齐值为8, 由于起始地址为1, 1 % 8 != 0 所以需要存放位置需要移后,我们发现 8 % 8 = 0 ,所以c的存放位置为8~15这几块第三个变量为a,对齐值为4,由于起始地址为17, 16 % 4 != 0 所以a的存放位置为17~20这几块最后,结构体的总大小需要 % 8 = 0 由于20 % 8 != 0 ,所以总大小为 24,因为 24 % 8 = 0 不要弄错了,不是说结构体的对齐值是多少那么结构体的大小就是简单的看看是不是n的倍数就可以了
- = ...额 我不是想问这个
是我表述有点问题结构体的对齐值为其中最大的变量的对齐值 不是结构体的大小计算对齐空间的地址时使用的余数是二者取小 就是对齐值二者取消这个我知道我的问题是上面两个规定的意义是什么 你一开始说了 防止破裂读取影响计算机的运算效率
我想求问的是 上面两个规定对于 防止破裂读取影响计算机的运算效率 有什么意义
最好能举例子谢谢您
第一种情况,考虑声明结构体数组的情形:struct test{};struct test foo[2];所以为了对齐考虑,必须使sizeof(struct test)为4的倍数。第二种情况,struct test2{};sizeof(struct test)为8,但struct test明显只需要对齐到4的倍数。所以,struct test2也对齐到4的倍数即可。
谢谢 那个 sizeof(struct test)是8 为什么struct test只需要对齐到4的倍数呢
刚走开了下,发现有人发你看例子了,那我就不发例子了,写一点这两个条件的证明吧。你的第一个问题:首先有一个条件:对于任何简单变量(即char,int,double等等)在其自身的对齐参数内都是对齐的。当简单变量随机组成一个新变量(即结构体时)假设一个结构体A内有n个简单变量,且结构体的对齐参数为y每个简单变量的对齐参数分别为x1,x2,x3...等,其中拥有最大对齐参数的变量为xn,且其对齐参数为n。现假设,如果此结构体A的对齐参数不为n的倍数同时结构体的大小也不为n的倍数:同时假设,我们有一个结构体A的实现 :A _a;这个_a的起始地址为Add_x当xn为结构体A的第一个参数时:即结构体的起始地址等于xn的起始地址那么对于任何起始地址Add_x总存在使得 : add_x % y = 0 但是add_x % xn != 0,所以这种情况下,必须保证最大对齐参数为xn的对齐参数.当xn为结构体A的第二个参数时:由于结构体的起始地址到xn的长度为定值(定义的时候就计算好了)即结构体的起始地址 + 定值 = xn的起始地址那么对于任何起始地址Add_x总存在使得 : add_x % y = 0 但是( add_x + 定值 ) % xn != 0,所以这种情况下,必须保证最大对齐参数为xn的对齐参数.依次类推,得证对于包含简单变量的新变量的对齐参数必须为最大变量的对齐参数。之后将我们证明后的新变量引入,得到任何包含新变量和简单变量的更新的变量(。。。)的对齐参数必须为最大变量的对齐参数。之后无限循环,得到这一条的证明。你的第二个问题:由第一个问题的结论可以得到:对于任何结构体X,它的对齐参数必须为最大变量的对齐参数。假设一个新的结构体Y包含结构体X那么Y的对齐参数必须&= X的对齐参数那么,当结构体X的对齐参数 &= Y内所有其他变量的对齐参数时。即若Y要保持对齐则只需要:Y的对齐参数 = X的对齐参数 = X内最大对齐参数变量的对齐参数。
不好意思,我没看清楚哈,第一个问题证明成对齐参数了。。。不过内存大小是一样地,关键就是变量的起始地址会不一样的原因。
哦 谢谢你 谢谢刚才我去理发了
登录百度帐号推荐应用c语言中变量存储为什么要内存对齐_百度知道
c语言中变量存储为什么要内存对齐
我有更好的答案
满足三个准则: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,但一般而言。字节对齐的细节和编译器实现相关,所以整个结构体的sizeof值就增长了。这样,两个数中间就可能需要加入填充字节,让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基数据类型(int等)都位于能被4整除的地址上,以此类推为了有助于加快计算机的取数速度,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此)
软件工程师
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年3月 C/C++大版内专家分月排行榜第三
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
本帖子已过去太久远了,不再提供回复功能。内存对齐到底是怎么回事? - 简书
内存对齐到底是怎么回事?
内存对齐问题是各种开发类面试中最热门的问题,面试管一般认为这个问题可以考察被面试者对内存细节的了解
情况,确实这个问题对于C++初学者来说是个十足的难题因为它不仅涉及了pragma pack(n) 设定的内存对齐系数
还涉及了相关内存分配的细节。
内存对齐:
我们知道现代计算机体系中CPU按照双字、字、字节访问存储内存,并通过总线进行传输,若未经一定规则的对齐,CPU的访址操作与总线的传输操作将会异常的复杂,所以现代编译器中都会对内存进行自动的对齐。
1.内存对齐系数
说道内存对齐,就不得不说内存对齐系数, 对齐系数最简单的设置方法是使用
进行设置,这部分点进链接在我的文章内有详细说明!
说到内存对齐第二个不得不说的就是sizeof,它的基本作用是判断数据类型或者表达式长度,要注意的是这不是一个函数,而是一个C++中的关键字!字节数的计算在程序编译时进行,而不是在程序执行的过程中才计算出来!
3.类型的长度与数据成员对齐
你的计算机中,数据类型的长度指的就是在你的计算机中对数据类型使用sizeof得到的结果,当然这个在各种不同的编译环境下得到的结果是不同的。
比如在32位Visual Studio环境下:
cout && sizeof(char) &&
cout && sizeof(short) &&
cout && sizeof(int) &&
cout && sizeof(long) &&
cout && sizeof(double) &&
而在64位G++编译环境下:
cout && sizeof(char) &&
cout && sizeof(short) &&
cout && sizeof(int) &&
cout && sizeof(long) &&
cout && sizeof(double) &&
下面我将在32位Visual Studio环境下讲解数据成员对齐:
  首先我们要清楚结构体struct中的成员在内存中的分配是连续的,struct内的首地址也就是struct内第一个数据成员的地址,换句话说struct内第一个数据成员离struct开始的距离offset = 0。
  数据成员对齐的规则就是,而在第一个成员之后,每个成员距离struct首地址的距离 offset, 都是struct内成员自身长度(sizeof) 与
中的n的最小值的整数倍,如果未经对齐时不满足这个规则,在对齐时就会在这个成员前填充空子节以使其达到数据成员对齐。
默认n为8时:
cout && sizeof myStruct &&
cout && (int *)&myStruct.a &&
cout && &myStruct.b &&
// (因运行时而异)
当设置n为4也就是min(sizeof(double), n) = 4 时:
#pragma pack(4)
cout && sizeof myStruct &&
cout && (int *)&myStruct.a &&
// 0046F76C
cout && &myStruct.b &&
第一个例子时,最小值为8,填充7个字节到char a 之后。
第二个例子时,最小值为4,填充3个字节到char a之后。
4.整体对齐
编译器在进行过数据成员对齐之后,还要进行整体对齐。与数据对齐相似但不是完全相同, 如果数据对齐完成时struct的大小不是 struct内成员自身长度最大值(sizeof) 与
#pragma pack(n)中的n的最小值的整数倍。(注意这里是成员中长度最大的那个与n比较,而不是特定的一个成员。)就要在struct的最后添加空字节直到对齐。
当设置n为4也就是min(sizeof(short), n) = 2 时:
#pragma pack(4)
cout && sizeof myStruct &&
cout && (int *)&myStruct.a &&
// 003DFED0
cout && &myStruct.b &&
// 003DFED2
cout && (int *)&myStruct.c &&
// 003DFED4
在上面的例子中,char a offset为0 因成员对齐占据[D0]填充[D1]共两个字节,short b是最大长度成员无需对齐占据[D2-D3]两个字节,它的offset是2,而char c的offset是4占据[D4]无需成员对齐,但此时struct的大小是2+2+1 = 5字节,不是2的整数倍,所以我们要填充空子节在最后直到struct大小达到2的整数倍,这就是整体对齐。
经过了数据成员对齐与整体对齐之后内存对齐就完成了,如果深入思考上述规则还会发现:即使是同样数目与数量的数据成员,在摆放的顺序不同时struct的大小也会不同,下面就是一个例子:
这样摆放是12字节:
12字节.png
结果是12字节.png
摆放方式改变时结果确变成了8字节:
却变成了8字节.png
由于这种特性,如果在网络编程或相关内存操作时如果不加以注意的话,就会造成隐秘而难以纠正的错误,请大家务必小心!
简书●null122转载请注明出处
我的主页是个什么地址?
转载请注明出处!
内存对齐: 我们知道现代计算机体系中CPU按照双字、字、字节访问存储内存,并通过总线进行传输,若未经一定规则的对齐,CPU的访址操作与总线的传输操作将会异常的复杂,所以现代编译器中都会对内存进行自动的对齐。 1.内存对齐系数 说道内存对齐,就不得不说内存对齐系数, 对齐系数...
回答: (以下大部分都是基于x64编译器下的windows平台的gcc version 5.3.0 (GCC)编译器的测试结果,不能其他平台也能得出完全一致的结论,如果在x32下编译结果会指出)由于class相较于struct,默认的成员就是private,代码中没有特地强...
写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?讲讲字节对齐吧. /******************************分割线如果体系结构是不对齐的,A中的成员将会一个挨一个存储,...
4.3:新增class的相关内容 今天看到一个题目: 最开始简单的理解为,每个数据的size之和就是偏移量。因为偏移量为8是因为两个int数据的大小。但这只是巧合,理解存在错误。因为我尝试了一下这样: 按上面的想法得到的应该是0,1,5,however,得到的是0,4,8改...
引言 C语言结构体内存布局是一个老生常谈的问题,网上也看了一些资料,有些说的比较模糊,有些是错误的。本人借鉴了前人的文章,经过实践,总结了一些规则,如有错误,希望指正,不胜感激。 实际环境 系统环境 macOS Sierra(10.12.4) IDE Xcode(8.3) ...
此词的争议很大,现代人多用hopefully来表示 I hope 和 we hope,但是教师和学者却很反对这种用法。 最好的解决方法是在需要用hopefully的时候改用I hope 或 we hope
今天逛街,我看中了一串石榴石手串,它就静静地挂在那里,流转的色泽是红酒酡醉的脸。 触手,冰凉。一如你看到一位陌生人的眼。手一抖,赶忙将它挂在树木式的支架上,闪闪烁烁的光泽与其他手串一起晃动着你的眼。 我希望它能和某种神秘的力量联系在一起,带上它,天长日久,能获得不一样的生机...
午后 蝉鸣阵阵 骄阳似火 上帝用这种方式审判着大地 灼烧的不只是身体 还有那浮燥的灵魂 人们流的汗便是对上帝的忏悔 一切的生灵与烈日抢夺水分 最终 挺过来的 便迎来了甘霖 挺不过来的 便成了一抔黄土 随风消散
为什么世界上有穷人和富人? 为什么人要活在世界上? 为什么人要学习? 为什么世界要发展创新? ………………为什么,为什么??? 啊哈,十万个为什么≧?≦}

我要回帖

更多关于 结构体变量的内存对齐 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信