c++打印类的内存布局

内存布局

  1. 默认32位编译下,4字节对齐
  2. 有虚函数情况下会在内存一开始多一个虚表指针
  3. 普通函数不占内存空间
  4. 静态成员不占内存空间

1. 通过cl命令输出hello.cpp中的类A的内存布局测试

# 输出指定类型的内存布局
cl hello.cpp /d1reportSingleClassLayoutA

# 输出所有类型的内存布局
cl hello.cpp /d1reportAllClassLayout
class A {
public:
    char x;
    int y;
    bool z;
};
  • 内存布局
class A size(12):
        +---
 0      | x
        | <alignment member> (size=3)
 4      | y
 8      | z
        | <alignment member> (size=3)
        +---

2. 虚函数/虚继承内存布局测试

class A {
public:
    virtual void foo() = 0;
    void bar() {};
    char x;
    int y;
    bool z;
};

class B : public A {
public:
    virtual void foo() override{};
    void bar() {};
    float b;
};

class C: virtual A {
public:
    virtual void foo() override {};
    void bar() {};
    double c;
    static bool c1;
};
  • 内存布局
class A size(16):
        +---
 0      | {vfptr}
 4      | x
        | <alignment member> (size=3)
 8      | y
12      | z
        | <alignment member> (size=3)
        +---

A::$vftable@:
        | &A_meta
        |  0
 0      | &A::foo

A::foo this adjustor: 0

class B size(20):
        +---
 0      | +--- (base class A)
 0      | | {vfptr}
 4      | | x
        | | <alignment member> (size=3)
 8      | | y
12      | | z
        | | <alignment member> (size=3)
        | +---
16      | b
        +---

B::$vftable@:
        | &B_meta
        |  0
 0      | &B::foo

B::foo this adjustor: 0

class C size(32):
        +---
 0      | {vbptr}
 8      | c
        +---
        +--- (virtual base A)
16      | {vfptr}
20      | x
        | <alignment member> (size=3)
24      | y
28      | z
        | <alignment member> (size=3)
        +---

C::$vbtable@:
 0      | 0
 1      | 16 (Cd(C+0)A)

C::$vftable@:
        | -16
 0      | &C::foo

3. 菱形继承内存布局测试

class A1 {
public:
    int a;
};

class B1 : public A1 {
public:
    int b;
};

class C1 : public A1 {
public:
    int c;
};

class D1 : public B1, public C1 {
public:
    int d;
};
  • 内存布局
class A1        size(4):
        +---
 0      | a
        +---

class B1        size(8):
        +---
 0      | +--- (base class A1)
 0      | | a
        | +---
 4      | b
        +---

class C1        size(8):
        +---
 0      | +--- (base class A1)
 0      | | a
        | +---
 4      | c
        +---

class D1        size(20):
        +---
 0      | +--- (base class B1)
 0      | | +--- (base class A1)
 0      | | | a
        | | +---
 4      | | b
        | +---
 8      | +--- (base class C1)
 8      | | +--- (base class A1)
 8      | | | a
        | | +---
12      | | c
        | +---
16      | d
        +---

4. 虚菱形继承测试

class A2 {
public:
    int a;
};

class B2 : virtual public A2 {
public:
    int b;
};

class C2 : virtual public A2 {
public:
    int c;
};

class D2 : public B2, public C2 {
public:
    int d;
};
  • 内存布局
class A2        size(4):
        +---
 0      | a
        +---

class B2        size(12):
        +---
 0      | {vbptr}
 4      | b
        +---
        +--- (virtual base A2)
 8      | a
        +---

B2::$vbtable@:
 0      | 0
 1      | 8 (B2d(B2+0)A2)
vbi:       class  offset o.vbptr  o.vbte fVtorDisp
              A2       8       0       4 0

class C2        size(12):
        +---
 0      | {vbptr}
 4      | c
        +---
        +--- (virtual base A2)
 8      | a
        +---

C2::$vbtable@:
 0      | 0
 1      | 8 (C2d(C2+0)A2)
vbi:       class  offset o.vbptr  o.vbte fVtorDisp
              A2       8       0       4 0

class D2        size(24):
        +---
 0      | +--- (base class B2)
 0      | | {vbptr}
 4      | | b
        | +---
 8      | +--- (base class C2)
 8      | | {vbptr}
12      | | c
        | +---
16      | d
        +---
        +--- (virtual base A2)
20      | a
        +---

D2::$vbtable@B2@:
 0      | 0
 1      | 20 (D2d(B2+0)A2)

D2::$vbtable@C2@:
 0      | 0
 1      | 12 (D2d(C2+0)A2)
vbi:       class  offset o.vbptr  o.vbte fVtorDisp
              A2      20       0       4 0

参考

https://www.cnblogs.com/zzqcn/p/4742295.html

posted @ 2023-07-24 13:32  BuzzWeek  阅读(128)  评论(0编辑  收藏  举报