引言

各种C++实现对C++类/对象的内存布局可能有所不同,包括数据成员的顺序、虚函数表(virtual table: vtbl)的结构、继承关系的处理等。了解C++类/对象的布局,对于理解C++各种机制,正确合理地进行设计和开发有很大的帮助。

主流编译器的支持

本文所述的3款主流编译器都提供打印/导出C++类/对象的内存布局的功能,现用表格列出其特性和用法,测试用的代码文件列于文后(data.cpp)

编译器及验证版本 用法 说明
gcc 4.8.4 gcc --fdump-class-hierarchy data.cpp

导出的布局图示在data.cpp同一目录下的一个.class文件中,

如data.cpp.002t.class,内容示例:

VTT for A
A::_ZTT1A: 4u entries
0 ((& A::_ZTV1A) + 24u)
8 ((& A::_ZTC1A0_1Y) + 24u)
16 ((& A::_ZTC1A8_1Z) + 24u)
24 ((& A::_ZTV1A) + 48u)

Class A
size=16 align=8
base size=16 base align=8
A (0x0x7f9dbc60c540) 0
vptridx=0u vptr=((& A::_ZTV1A) + 24u)
Y (0x0x7f9dbc5c11a0) 0 nearly-empty
primary-for A (0x0x7f9dbc60c540)
subvttidx=8u
X (0x0x7f9dbc5ccae0) 0 empty virtual
vbaseoffset=-24
Z (0x0x7f9dbc5c1208) 8 nearly-empty
subvttidx=16u vptridx=24u vptr=((& A::_ZTV1A) + 48u)
X (0x0x7f9dbc5ccae0) alternative-path

clang 3.4 clang -Xclang -fdump-record-layouts data.cpp

要求data.cpp中有对相关类做sizeof求值的语句,输出在stdout,类似

*** Dumping AST Record Layout
0 | class A
0 | class Y (primary base)
0 | (Y vtable pointer)
8 | class Z (base)
8 | (Z vtable pointer)
0 | class X (virtual base) (empty)
| [sizeof=16, dsize=16, align=8
| nvsize=16, nvalign=8]

VC++ 2010

添加编译选项

/d1reportSingleClassLayout<类名> :输出单个类相关布局

/d1reportAllClassLayout: 输出所有类相关布局

编译时输出在“输出”窗口中,类似如下:

1> class A size(8):
1> +---
1> | +--- (base class Y)
1> 0 | | {vbptr}
1> | +---
1> | +--- (base class Z)
1> 4 | | {vbptr}
1> | +---
1> +---
1> +--- (virtual base X)
1> +---
1>
1> A::$vbtable@Y@:
1> 0 | 0
1> 1 | 8 (Ad(Y+0)X)
1>
1> A::$vbtable@Z@:
1> 0 | 0
1> 1 | 4 (Ad(Z+0)X)

测试所用代码文件

data.cpp

#include <cstdio>

class X {};
class Y : public virtual X {};
class Z : public virtual X {};
class A : public Y, public Z {}; int main(int argc, char** argv)
{
printf("Ptr: %lu\n", sizeof(void*)); printf("X: %lu\n", sizeof(X));
printf("Y: %lu\n", sizeof(Y));
printf("Z: %lu\n", sizeof(Z));
printf("A: %lu\n", sizeof(A)); return ;
}

【C++对象模型】使用gcc、clang和VC++显示C++类的内存布局的更多相关文章

  1. VC++中的类的内存分布(上)

    0.序 目前正在学习C++中,对于C++的类及其类的实现原理也挺感兴趣.于是打算通过观察类在内存中的分布更好地理解类的实现.因为其实类的分布是由编译器决定的,而本次试验使用的编译器为VS2015 RC ...

  2. VC++中的类的内存分布(上)(通过强制转换,观察地址,以及地址里的值来判断)

    0.序 目前正在学习C++中,对于C++的类及其类的实现原理也挺感兴趣.于是打算通过观察类在内存中的分布更好地理解类的实现.因为其实类的分布是由编译器决定的,而本次试验使用的编译器为VS2015 RC ...

  3. 浅析GCC下C++多重继承 & 虚拟继承的对象内存布局

    继承是C++作为OOD程序设计语言的三大特征(封装,继承,多态)之一,单一非多态继承是比较好理解的,本文主要讲解GCC环境下的多重继承和虚拟继承的对象内存布局. 一.多重继承 先看几个类的定义: 01 ...

  4. VC中结构体的内存布局

    看了 VC++中内存对齐 这篇文章,感觉说复杂了,根据我的总结,要算出结构体的内存大小和偏移量,只要清楚结构体各成员的内存布局就行了,下面介绍一下我总结的规则,有不对之处,欢迎回复. 1.实际PACK ...

  5. 图说C++对象模型:对象内存布局详解

    0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看. 本文的结论都在VS2013上得到验证.不同的编译器在内存布局的细节上可能有 ...

  6. 好文章系列C/C++——图说C++对象模型:对象内存布局详解

    注:收藏好文章,得出自己的笔记,以查漏补缺!     ------>原文链接:http://blog.jobbole.com/101583/ 前言 本文可加深对C++对象的内存布局.虚表指针.虚 ...

  7. 【转载】图说C++对象模型:对象内存布局详解

    原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在 ...

  8. Vc++内存布局

    Vc++内存布局 测试平台 Windows server 2012 R2 and visual studio 2013 professional. 本篇文章意在介绍vc++中类的内存布局方式,只是研究 ...

  9. 虚继承之单继承的内存布局(VC在编译时会把vfptr放到类的头部,这和Delphi完全一致)

    C++2.0以后全面支持虚函数与虚继承,这两个特性的引入为C++增强了不少功能,也引入了不少烦恼.虚函数与虚继承有哪些特性,今天就不记录了,如果能搞了解一下编译器是如何实现虚函数和虚继承,它们在类的内 ...

随机推荐

  1. SimpleReflection

    [SimpleReflection] 取法线的x.y作为reflection-map的uv. Shader "Custom/SimpleReflection" { Properti ...

  2. NPOI工具类

    NPOI调用方法 DataTable dt = new DataTable(); Dictionary<string, string> header = new Dictionary< ...

  3. Spring IOC容器启动流程源码解析(四)——初始化单实例bean阶段

    目录 1. 引言 2. 初始化bean的入口 3 尝试从当前容器及其父容器的缓存中获取bean 3.1 获取真正的beanName 3.2 尝试从当前容器的缓存中获取bean 3.3 从父容器中查找b ...

  4. ASP.NET 网页动态添加客户端脚本

    在System.Web.UI.Page类中包含了RegisterStarupScript()和RegisterClientScriptBlock()两个方法,使用这两个方法可以实现向Web页面动态添加 ...

  5. Ubuntu18.04安装Virtualenv虚拟环境

    在Ubuntu18.04安装Virtualenv虚拟环境 [实验环境]: 在这台电脑上已经安装了python3 [安装参考] 1.查看是否已安装virtualenv virtualenv --vers ...

  6. loadrunner--vugen录制脚本提示“无Internet访问。您可能无法录制并执行业务进程”

    1.vugen录制脚本提示如下,为什么会提示这个呢?这个提示忽略会对录制脚本有影响吗?最好应该怎么操作? 惠普技术支持回复: 您可以试试,若点击“Yes”,是否可以继续录制网站?若可以的话,您也确定网 ...

  7. Luogu 3321 [SDOI2015]序列统计

    BZOJ 3992 点开这道题之后才发现我对原根的理解大概只停留在$998244353$的原根是$3$…… 关于原根: 点我 首先写出$dp$方程,设$f_{i, j}$表示序列长度为$i$当前所有数 ...

  8. background image

    http://www.ajaxblender.com/bgstretcher-2-jquery-stretch-background-plugin-updated.html http://blog.d ...

  9. SOCK开发之---TCP/IP简介

    在开发通信程序之前,都要先确定这些程序相互通信所使用的协议(protocol),在深入设计前,我们都需要先从高层次来判断通信由哪个程序发起以及相应在何时产生. 举例来说,一般认为web服务器是一个长时 ...

  10. Github 的注册教程和初步使用体验

    我叫许晴,是网工143的学生,学号是1413042064,兴趣包括手绘,看书和手游.学习过c++和汇编语言课程,但在编程方面没什么独立实践经验. 我的Githup用户名是 XQ123 .下面是我在gi ...