解析g++ -fdump-lang-class生成的.class文件中类字段及地址差异
关于g++
-fdump-lang-class输出中类地址与偏移的疑问解析 我在学习C++类内存模型(如vtable、vptr等)时,使用g++ -fdump-lang-class命令生成.class文件查看类内存布局,测试代码如下:
class A { public: void func() {} private: int a; }; class B : public A { public: void func() {} private: int b; int c; };
生成的.class文件内容为:
Class A size=4 align=4 base size=4 base align=4 A (0x0x7f3a29771ae0) 0 Class B size=12 align=4 base size=12 base align=4 B (0x0x7f3a296201a0) 0 A (0x0x7f3a29771ba0) 0
问题
想了解:Class A中的A (0x0x7f3a29771ae0) 0以及Class B中的A (0x0x7f3a29771ba0) 0里,“0x0x...”和“0”的含义是什么?为何这两个A的地址不同?
解析
末尾的“0”的含义:这是基类子对象在派生类对象内存中的字节偏移量。比如Class B条目下的A后面的0,表示A的子对象位于B对象内存的起始位置(偏移0字节),这是C++单继承的默认布局规则——基类子对象会被放在派生类对象的最前面。而独立Class A条目后的0,因为它没有基类,所以偏移量为0。
“0x0x...”地址的含义:这是g++编译器内部用来标识类的唯一元数据结构指针地址。编译过程中,编译器会为每个类(包括基类在派生类上下文中的实例)创建内部数据结构,存储类的成员布局、继承关系、访问权限等元信息,这个地址就是指向该数据结构的指针。
两个A地址不同的原因:这两个地址对应的是编译器内部的不同元数据结构。一个是独立的Class A的元数据指针,另一个是作为B的基类的A的元数据指针——虽然逻辑上是同一个类,但在派生类的上下文里,编译器需要记录基类在派生类中的偏移、布局适配等额外信息,因此会为其创建专门的元数据结构,所以两者地址不同。
内容的提问来源于stack exchange,提问作者jiafeng chen
相关产品推荐
相关产品推荐

