准确了解对象在内存中的映射方式
understanding exactly how an object is mapped in memory
我读了这个问题和其他一些关于对象布局的问题,但我仍然不明白它的外观。
这是我的具体问题:
对于每个类(这意味着如果我有一个 2 个超类,我将有 2 个指针(,虚函数对它们有 1 个vtable pointer
。 它在对象内部的什么位置?假设以下内容:class A{void virtual f(){}; int x;};
对象的地址A a
与a.x
或a.f
的地址相同[或者可能指向默认方法,例如不正确,因为类方法未存储在对象中,如此处所述]C-tor / D-tor
例:
class A{
int x;
void f(){}
void virtual g(){}
void virtual h(){}
};
A a;
std::cout << sizeof a; // result = 8
class A{
int x;
void f(){}
void virtual g(){}
};
A a;
std::cout << sizeof a; // result = 8
class A{
int x;
void f(){}
//void virtual g(){}
};
A a;
std::cout << sizeof a; // result = 4
从这些例子可以看出,当遇到一个虚函数的数量(n> 0(时,一个指针(在我的 32 位机器上为 4 个字节(被添加到对象中。是否会将其添加到其他数据成员之前?
将指出什么:
A a;
int *p = (int*)&a;
我用这个检查了一下。从下面假设 vtable 指针总是在其他类成员之前是否正确?
class A{
public:
A(int y){x=y;}
virtual void g(){}
int x;
virtual void f(){}
};
int main ()
{
A a(42);
int *p = (int*)&a;
std::cout << *p << std::endl; // = 4215116 (vtable address?)
std::cout << *(p+1) << std::endl; // = 42
return 0;
}
这完全依赖于实现(编译器(,大多数实现倾向于插入 vptr 作为第一个元素。由于它是对象地址的第一个元素和开头,因此虚拟函数调用调用的间接寻址将更容易,因为没有进一步的偏移量计算来标识 vptr。之前在stackoverflow中提出类似的问题,发现下面的问题很有用。 为什么 vptr 作为具有虚函数的类的内存中的第一个条目存储?
相关文章:
- 准确了解对象在内存中的映射方式
- 将布局映射到内存地址
- 数组中未映射的内存访问从python传递到c++
- 您可以将C 对象映射到内存映射的外围设备吗?
- 一维数组映射方式的性能差异问题
- 我如何正确地为std ::映射分配内存
- 如何通过文件映射对象重新映射共享内存的视图?
- 如何在Windows和更高版本上保留内存,并将文件映射到内存中
- Qt-添加元素到映射和内存泄漏
- 任何查找分配给映射的内存大小的方法
- 我插入 STL 映射的方式是否正确?不会漏内存吗?
- 我什么时候应该首选写入组合 CUDA 分配的映射主机内存
- 我可以将可搜索字符设备“/dev/mem_8”映射到内存并使用x86_64指令访问它吗?
- 将几个大文件映射到内存
- 将二维空间中的项目映射到内存中
- std::映射导致内存泄漏
- 将一个文件映射到内存,然后获取到该内存的文件描述符
- 读取映射到内存的CSV文件的最简单方法
- 带有映射的内存泄漏
- 在C++中,在不损失速度的情况下提高元组映射的内存消耗