如何读取指向派生类的基类指针数组的内存布局
How to read memory layout of an array of base class pointers pointing to derived class
我做了一些实验,以了解基类指针数组的内存布局
。问题>初始化后(案例I和II(,为什么每个指针之间的距离是20
字节。这个数字从何而来?
谢谢
#include <iostream>
using namespace std;
class A {
public:
virtual void PrintMe() const {
cout << "class A; ";
}
~A() {}
};
class B : public A {
private:
int num;
public:
virtual void PrintMe() const {
cout << "class B; ";
}
};
int main() {
int a[2];
cout << "&a[0]: " << hex << &a[0] << endl;
cout << "&a[1]: " << hex << &a[1] << endl;
cout << "sizeof(int): " << sizeof(int) << endl;
cout << "sizeof(int*): " << sizeof(int*) << endl;
cout << "sizeof(A): " << sizeof(A) << endl;
cout << "sizeof(A*): " << sizeof(A*) << endl;
cout << "sizeof(B): " << sizeof(B) << endl;
cout << "sizeof(B*): " << sizeof(B*) << endl;
A* vec[5];
cout << "Before initializatiion: " << endl;
for(int i=0; i < 5; ++i)
{
cout << "vec[" << i << "]: " << hex << vec[i] << endl;
}
cout << "After initialization with A* ONLY: " << endl; // case I
for(int i=0; i < 5; i++)
vec[i] = new A();
for(int i=0; i < 5; ++i)
{
vec[i]->PrintMe();
cout << "vec[" << i << "]: " << hex << vec[i] << endl;
}
cout << "After initialization with B* & A*: " << endl; // case II
for(int i = 0; i < 3; i++)
vec[i] = new B();
for(int i=3; i < 5; i++)
vec[i] = new A();
for(int i=0; i < 5; ++i)
{
vec[i]->PrintMe();
cout << "vec[" << i << "]: " << hex << vec[i] << endl;
}
return 0;
}
输出:
&a[0]: 0x7fff0a6d3c40
&a[1]: 0x7fff0a6d3c44
sizeof(int): 4
sizeof(int*): 8
sizeof(A): 8
sizeof(A*): 8
sizeof(B): 10
sizeof(B*): 8
Before initializatiion:
vec[0]: 0x2
vec[1]: 0x4011ed
vec[2]: 0x7f7b9a2a6a70
vec[3]: 0x401190
vec[4]: 0
After initialization with A* ONLY:
class A; vec[0]: 0xc51010
class A; vec[1]: 0xc51030
class A; vec[2]: 0xc51050
class A; vec[3]: 0xc51070
class A; vec[4]: 0xc51090
After initialization with B* & A*:
class B; vec[0]: 0xc510b0
class B; vec[1]: 0xc510d0
class B; vec[2]: 0xc510f0
class A; vec[3]: 0xc51110
class A; vec[4]: 0xc51130
当您使用以下方法填充指针数组时:
for(int i=0; i < 5; i++)
vec[i] = new A();
不能保证vec[1]
和vec[0]
之间的差异与sizeof(A)
有任何关系。对此给予任何意义是没有意义的。
如果您使用:
A aArray[5];
for(int i=0; i < 5; i++)
vec[i] = &(aArray[i]);
保证vec[1]
和vec[0]
之间的差异是sizeof(A)
。
您看到连续分配之间的字节为 32 个字节。 没有什么可以保证这将是一个固定的(甚至增加的(值,只是每个分配都是唯一且不重叠的(直到你解除分配其中一些,然后它可以重用(。
因此,并不是说任何东西的大小都是 32 字节,而是标准库分配器的对齐方式。 这是明智的,因为通用分配需要与平台上所需的最大可能对齐对齐。 32 字节相当于 256 位 AVX 寄存器。
相关文章:
- 如何使用基类指针引用派生类成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 使用基类指针调用基类的值构造函数的语法是什么?
- 如何在基类指针向量的元素上应用重载的多态函数
- C++函数解析基类指针到派生类指针
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 我们可以在不知道其真实类型的情况下将基类指针转换为派生类指针吗?
- 从基类指针派生派生类的模板类型
- 当键是虚拟继承中涉及的基类指针时,对 std::unordered_map 项的访问崩溃
- 如何使用函数(而不是构造函数)将派生类对象分配给基类指针
- 创建基类指针的向量并将派生类对象传递给它(多态性)
- 无法将派生类存储在基类指针的向量中
- 有没有办法在没有虚拟的情况下使用基类指针调用派生类函数
- 基类指针:在哪里使用 new 和 delete
- 如何在CRTP实现中传递基类指针
- C++继承从基类指针访问派生类中的非虚拟函数
- 通过基类指针获取派生类对象的引用
- C++通过基类指针提升子类的序列化
- 将派生对象分配给函数内的基类指针
- 如果基类指针无法访问派生类成员函数,那么多态性有什么方便的呢?