c++内存对齐原理
转载自http://blog.csdn.net/it_yuan/article/details/24651347
#类中的元素
0. 成员变量 1. 成员函数 2. 静态成员变量 3. 静态成员函数 4. 虚函数 5. 纯虚函数
#影响对象大小的因素
0. 成员变量 1. 虚函数表指针(_vftptr) 2. 虚基类表指针(_vbtptr) 3. 内存对齐
_vftptr、_vbtptr的初始化由对象的构造函数, 赋值运算符自动完成;对象生命周期结束后,由对象的析构函数来销毁。
对象所关联的类型(type_info),通常放在virtual table的第一个slot中。
虚继承:在继承定义中包含了virtual关键字的继承关系;
虚基类:在虚继承体系中的通过virtual继承而来的基类,需要注意的是:
class CDerive : public virtual CBase {}; 其中CBase称之为CDerive的虚基类,而不是说CBase就是个虚基类,因为CBase还可以为不是虚继承体系中的基类。
虚函数被派生后,仍然为虚函数,即使在派生类中省去virtual关键字。
注:【下文中_vbptr即_vbtptr】
#对象内存布局分类讨论
vc6变量查看器中(Locals,Watch1等),也可以看到部分对象布局的情况(不完整,且虚继承是错误的)。
vs2005及以后版本的编译器提供了/d1reportSingleClassLayout[类名]编译选项来查看对象完整的内存布局:
cl classLayout.cpp /d1reportSingleClassLayoutCChildren
0. 单一类
(1). 空类

sizeof(CNull)=1(用于标识该对象)
(2). 只有成员变量的类

int nVarSize = sizeof(CVariable) = 12

内存布局:

(3). 只有虚函数的类

int nVFuntionSize = sizeof(CVFuction) = 4(虚表指针)

内存布局:

(4). 有成员变量、虚函数的类

int nParentSize = sizeof(CParent) = 8

内存布局:

1. 单一继承(含成员变量、虚函数、虚函数覆盖)

int nChildSize = sizeof(CChildren) = 12
vc中显示的结果(注:还有1个虚函数CChildren::g1没有被显示出来):

d1reportSingleClass查看:

内存布局:

2. 多继承 (含成员变量、虚函数、虚函数覆盖)

int nChildSize = sizeof(CChildren) = 20
vc中显示的结果(注:还有2个虚函数CChildren::f2,CChildren::h2没有被显示出来,this指针的adjustor[调整值]也没打印出):

d1reportSingleClass查看:

内存布局:

3. 深度为2的继承(含成员变量、虚函数、虚函数覆盖)

int nGrandSize = sizeof(CGrandChildren) = 24
vc中显示的结果(注:还有3个虚函数CGrandChildren::f2,CChildren::h2,CGrandChildren::f3没有显示出来,this指针的adjustor[调整值]也没打印出):

d1reportSingleClass查看:

内存布局:

4 重复继承(含成员变量、虚函数、虚函数覆盖)

int nGrandSize = sizeof(CGrandChildren) = 28
vc中显示的结果(注:还有大量的虚函数没有显示出来,this指针的adjustor[调整值]也没打印出):
thunk函数:一种形实转换辅助函数;主要做this指针调整,函数调用重定向。

d1reportSingleClass查看:

内存布局:

由于m_nAge在内容中存在两个拷贝,因此我们不能直接通过pGrandChildrenA->m_nAge来访问该变量,
这样会存在二义性,编译器无法知道应该访问CChildren1中的m_nAge,还是CChildren2中的m_nAge。
为了标识唯一的m_nAge,就需要带上其所在范围的类名了。如下:
1 pGrandChildrenA->CChildren1::m_nAge = 1;
2 pGrandChildrenA->CChildren2::m_nAge = 2;
5. 单一虚继承(含成员变量、虚函数、虚函数覆盖)

int nChildSize = sizeof(CChildren) = 20
d1reportSingleClass查看:

内存布局:

6. 多虚继承(含成员变量、虚函数、虚函数覆盖)
(1) virtual CParent1, CParent2

int nChildSize = sizeof(CChildren) = 24
d1reportSingleClass查看:

内存布局:

(2) CParent1, virtual CParent2

int nChildSize = sizeof(CChildren) = 24
d1reportSingleClass查看:

内存布局:

(3) virtual CParent1, virtual CParent2

int nChildSize = sizeof(CChildren) = 28
d1reportSingleClass查看:

内存布局:

7. 钻石型的虚拟多重继承(含成员变量、虚函数、虚函数覆盖)

int nGrandChildSize = sizeof(CGrandChildren) = 36
d1reportSingleClass查看:
thunk函数:一种形实转换辅助函数;主要做this指针调整,函数调用重定向。

内存布局:

#外部参考
参考链接:http://blog.csdn.net/yangshuangtao/article/details/45192149
c++内存对齐原理的更多相关文章
- C语言内存对齐原理
一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这 ...
- 重磅硬核 | 一文聊透对象在 JVM 中的内存布局,以及内存对齐和压缩指针的原理及应用
欢迎关注公众号:bin的技术小屋 大家好,我是bin,又到了每周我们见面的时刻了,我的公众号在1月10号那天发布了第一篇文章<从内核角度看IO模型的演变>,在这篇文章中我们通过图解的方式以 ...
- C/C++: C++位域和内存对齐问题
1. 位域: 1. 在C中,位域可以写成这样(注:位域的数据类型一律用无符号的,纪律性). struct bitmap { unsigned a : ; unsigned b : ; unsigned ...
- C语言再学习之内存对齐
昨天看Q3的代码,看到有个_INTSAIZEOF的宏,着实晕了一阵.一番google后,终于明白,这个宏的作用是求出变量占用内存空间的大小,先看看_INTSAIZEOF的定义吧: #define _I ...
- C结构体中数据的内存对齐问题
转自:http://www.cnblogs.com/qwcbeyond/archive/2012/05/08/2490897.html 32位机一般默认4字节对齐(32位机机器字长4字节),64位机一 ...
- 2的m次方 内存对齐
在存储的时候,为了提高效率,一般都会让偏移量落在2的m次方的位置上,而且常有向上取整和向下取整两种需求.向下取整PALIGN_DOWN(x,align) (x & (- align)) 这样 ...
- Net的struct的内存对齐问题
很少有人谈起struct的内存对齐问题, 就是在很多C#书中, 也很少提及. 但在实际应用中, 如果不注意内存对齐, struct比较大的话, 则会浪费一定的内存. 先从一个实例看起. publ ...
- c++中类对象的内存对齐
很多C++书籍中都介绍过,一个Class对象需要占用多大的内存空间.最权威的结论是: *非静态成员变量总合.(not static) *加上编译器为了CPU计算,作出的数据对齐处理.(c语言中面试中经 ...
- C/C++中的内存对齐问题和pragma pack命令详解
这个内存对齐问题,居然影响到了sizeof(struct)的结果值.突然想到了之前写的一个API库里,有个API是向后台服务程序发送socket请求.其中的socket数据包是一个结构体.在发送soc ...
随机推荐
- zookeeper安装使用及工作原理分析
1. Zookeeper概念简介 Zookeeper是一个分布式协调服务:就是为用户的分布式应用程序提供协调服务,它是集群的管理者,监视着集群中各个节点的状态,根据节点提交的反馈进行下一步合理操作. ...
- java代码实现ftp服务器的文件上传和下载
java代码实现文件上传到ftp服务器: 1:ftp服务器安装: 2:ftp服务器的配置: 启动成功: 2:客户端:代码实现文件的上传与下载: 1:依赖jar包: 2:sftpTools 工具类: ...
- 几个js 拓扑图库
计划做一个元数据平台, 因为要包含血缘分析功能, 所以要调研一下js 拓扑图库, 候选对象主要参考知乎上的问答, javascript 有哪些适合做网络拓扑图形展示的包? https://www.zh ...
- 向量空间模型(Vector Space Model)的理解
1. 问题描述 给你若干篇文档,找出这些文档中最相似的两篇文档? 相似性,可以用距离来衡量.而在数学上,可使用余弦来计算两个向量的距离. \[cos(\vec a, \vec b)=\frac {\v ...
- Javaweb学习笔记——(十七)——————JDBC的原理、四大核心类、四大参数、预编译、Dao模式、批处理、大数据、时间类型的转换
JDBC入门 *导入jar包:驱动 *加载驱动类:Class.forName("类名"); *给出url.username.password,其中url背下来 *使用DriverM ...
- HDB3 译码器
一.HDB3译码方案一: 插入V/B的情况是有两种,两个或三个零两端同极性,也就是要把代码二进制表示的“+1 0 0 0 +1”或“-1 0 0 0 -1”变成“1 0 0 0”,把“+1 0 0 + ...
- nginx 完成缓存清除 以及升级包的自动升级
#!/bin/bash function cache(){ for i in `curl xxx.fe.xxx.cn/uplist.txt`;do url=`echo $i|awk -F"# ...
- steps/train_sat.sh
<<LDA_MLLT_fMLLR三音素HMM的训练流程图.vsdx>>
- Python常用模块之time模块
python中的time和datetime模块是时间方面的模块 time模块中时间表现的格式主要有三种: 1.timestamp:时间戳,时间戳表示的是从1970年1月1日00:00:00开始按秒计算 ...
- .innerhtml 与.innertext
示例代码: <div id="test"> <span style="color:red">test1</span> tes ...