C++成员对齐方式探讨
本文參考了《高质量程序设计指南——C++/C语言》一书
有不妥之处恳请指正
一、自然对齐
某些基于RISC(精简指令集)的CPU比方SPARC、PowerPC等。採用高字节和高字在低地址存放、低字节和低字在高地址存放的大端模式存储。而且把最高字节的地址作为变量的首地址。
在这样的自然的存储格式中,要求变量在内存中的存放位置必须自然对齐,否则CPU会报告异常。所谓自然对齐,就是基本数据类型(主要是short、int、double)的变量不能简单地存储于内存中的随意地址处。它们的起始地址必须可以被它们的大小整除。
比如。在32位平台下,int和指针类型变量的地址应该能被4整除。而short变量的地址应该都是偶数,bool和char则没有要求。所以。基于这样的CPU架构的平台,编译器将依照自然对齐的要求来为每一个变量生成逻辑地址,C++/C编译器亦如此。
而Intel系列CPU採用小端模式来存放基本类型变量,即低字节和低字在低地址存放、高字节和高字在高地址存放。而且把最低字节的地址作为变量的首地址。在Intel系列CPU这样的硬件平台上。并不严格要求基本数据类型变量在内存中必须自然对齐,相同也不会要求复合类型变量必须自然对齐。可是VC++在处理程序时,为了提高CPU的处理速度,对复合类型变量做了成员对齐处理。
二、成员对齐
VC++在处理复合数据类型成员变量时默认遵循下面三种原则:
(1) 复合类型对象的首地址要能被占用字节数最多的成员变量的字节数整除。
(2) 复合类型对象占用的内存空间大小要能被占用字节数最多的成员变量的字节数整除。
(3) 各成员变量存放的起始地址相对于复合结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。
举比例如以下:
struct exm
{
bool a;
double b;
bool c;
};
它是怎么存储的?
首先,在内存中找一个能被8整除的起始地址。然后分配24个字节。
为什么是24个而不是10个?或者是16个?
这是由于原则(3)的缘故,变量b占8个字节,那么它相对于结构的起始地址的偏移量必须为8的倍数,因此尽管a仅仅占一个字节,但后面会补上7个字节。
那么为什么变量c也占8个字节啊?这是由于原则(2)的缘故。由于在结构体exm中。占用字节数最多的是变量b。8个字节,所以exm占用的空间大小应能被8整除,如今a和b已经占用16个字节了,而c至少要占用一个字节,因此会在c后补上7个字节,变成24个字节。
把exm成员调换一下。变为:
struct exm
{
double b。
bool a。
bool c;
};
它的大小就变成16个字节了。
当然,我们也能够在程序中指定对齐方式。这时上述原则将不再成立。假设在程序中指定对齐方式。则对于复合结构中的变量,假设占用空间不足指定对齐字节。且假设依照默认对齐方式占用的空间将比指定的对齐方式大,则将按指定对齐方式补足,比如:
#pragmapack(4) //依照4字节边界对齐
struct exm
{
bool a;
double b;
bool c;
};
在VS2010中,它占用16个字节空间。
分析:变量a假设依照默认对齐方式要占8位,但它本身是bool型变量,占一位,指定对齐方式为4字节对齐,则a将被补齐为4字节。同理变量c也一样。
把exm成员换一下位置:
#pragmapack(4) //依照4字节边界对齐
struct exm
{
double b;
bool a;
bool c。
};
则exm占12位。
C++成员对齐方式探讨的更多相关文章
- 关于arm处理器 内存编址模式 与 字节对齐方式 (转)
转自:http://bavon.bokee.com/5429805.html 在x86+Linux上写的程序,在PC机上运行得很好.可是使用ARM的gcc进行交叉编译,再送到DaVinci目标板上运行 ...
- C# 使用 StructLayoutAttribute 时 C# /C++ 内存空间分配与成员对齐问题
1. 使用场景 公共语言运行时控制数据字段的类或结构在托管内存中的物理布局.但是,如果想要将类型传递到非托管代码,需要使用 StructLayout 属性. 2. 内存分配问题. 如果不显示的设置内存 ...
- C语言中内存对齐方式
一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问, ...
- struct的成员对齐问题-结构体实际大小问题
struct的成员对齐 注意:为了方便说明,等号左边是每个数据单独所占长度,右边是最终空间大小,以字节为单位. 一.什么时间存在对其问题:(32位机对齐方式是按照4字节对其的,以下所有试验都是在32位 ...
- C++ 学习笔记3,struct长度測试,struct存储时的对齐方式
之所以专门为struct的长度写一篇測试,是由于原来c++对于struct的变量, 在分配内存的时候,c++对struct有一种特殊的存储机制. 看以下的測试: 一.在Windows7 32bit , ...
- 从零开始学C++之IO流类库(四):输出流格式化(以操纵子方式格式化 以ios类成员函数方式格式化)
一.以操纵子方式格式化 数据输入输出的格式控制使用系统头文件<iomanip>中提供的操纵符.把它们作为插入操作符<<的输出对象即可.如setiosflags.setw.set ...
- 输出流格式化(以操纵子方式格式化,以ios类成员函数方式格式化)
一.以操纵子方式格式化 数据输入输出的格式控制使用系统头文件<iomanip>中提供的操纵符.把它们作为插入操作符<<的输出对象即可.如setiosflags.setw.set ...
- <转> Struct 和 Union区别 以及 对内存对齐方式的说明
转载地址:http://blog.csdn.net/firefly_2002/article/details/7954458 一.Struct 和 Union有下列区别: 1.在存储多个成员信息时,编 ...
- C/C++ struct定义、声明、对齐方式
一.定义/声明方式 第一种:仅有结构体名,不定义/声明变量 struct MyStruct { int i: char a[10]; double b; }:第二种:有结构体名,并声 ...
随机推荐
- IKanalyzer、ansj_seg、jcseg三种中文分词器的实战较量
转自:http://lies-joker.iteye.com/blog/2173086 选手:IKanalyzer.ansj_seg.jcseg 硬件:i5-3470 3.2GHz 8GB win7 ...
- Scala-基础-流程控制语句
import junit.framework.TestCase import scala.util.control.Breaks._ //流程控制语句 //关键字 if else match clas ...
- FCC 基础JavaScript 练习6
1.对象和数组很相似,数组是通过索引来访问和修改数据,对象是通过属性来访问和修改数据的, 对象适合用来存储结构化数据,就和真实世界的对象一模一样,比如一只猫. 任务 创建一个叫做myDog的对象,它里 ...
- python与arduino串口通讯对接opencv实现智能物品分拣
2018-05-0118:53:50 先上图: 再来视频: http://v.youku.com/v_show/id_XMzU3NzAwNzMyNA==.html?spm=a2hzp.8244740. ...
- 【sqli-labs】 less62 GET -Challenge -Blind -130 queries allowed -Variation1 (GET型 挑战 盲注 只允许130次查询 变化1)
允许130次尝试,然后是个盲注漏洞,看来要单字符猜解了 加单引号,页面异常,但报错被屏蔽了 http://192.168.136.128/sqli-labs-master/Less-62/?id=1' ...
- WindowsForms获取服务名称
StringBuilder sb = new StringBuilder(); ServiceController[] services = ServiceController.GetServices ...
- mysql如何将一个字段多个类型串成一个字符串?
结论 先说结论,可以使用group_concat group by的组合实现多行变一行,将一个字段的多个类型串成一个字段 需求: 如题,一个字段如电影类别,一部电影可以是多个类别,如喜剧.动作片等,其 ...
- buf.readUIntBE()
buf.readUIntBE(offset, byteLength[, noAssert]) buf.readUIntLE(offset, byteLength[, noAssert]) offset ...
- BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...
- 【Codeforces 369C】 Valera and Elections
[链接] 我是链接,点我呀:) [题意] 给你一棵树 让你选择若干个修理点. 这些修理点被选中之后,节点i到1号节点之间的所有"坏路"都会被修好 问最少需要选择多少个点才能将所有的 ...