Dyn*_*ite 9 c++ memory memory-management pod
对象如何在C++中存储在内存中?
对于常规课程,如
class Object
{
public:
int i1;
int i2;
char i3;
int i4;
private:
};
Run Code Online (Sandbox Code Playgroud)
使用Object作为数组的指针可以用来访问i1如下?
((Object*)&myObject)[0] === i1?
Run Code Online (Sandbox Code Playgroud)
关于SO的其他问题似乎暗示将结构转换为指针将指向POD类型的第一个成员.如果有构造函数的类,这有什么不同?另外,对于非POD类型,它有何不同?
编辑:
因此,在记忆中,上述课程的布局如下:
[i1 - 4bytes][i2 - 4bytes][i3 - 1byte][padding - 3bytes][i4 - 4bytes]
Run Code Online (Sandbox Code Playgroud)
Lar*_*itz 16
几乎.你转换为一个Object*,而忽略了一个地址.让我们重新询问如下:
((int*)&myObject)[0] == i1
Run Code Online (Sandbox Code Playgroud)
你必须非常小心这样的假设.正如您已定义的结构一样,在您可能遇到的任何编译器中都应如此.但是,正如其他人所说,对象的各种其他属性(你可能已经从你的例子中省略)将使其成为非POD并且可能(可能以编译器相关的方式)使上述陈述不正确.
请注意,如果你问过i3,我就不会这么快告诉你它会起作用 - 在这种情况下,即使对于普通的POD,对齐或字节顺序也很容易搞砸你.
无论如何,如果可能的话,你应该避免这种事情.即使它现在工作正常,如果你(或任何不理解你正在做这个技巧的人)改变结构顺序或添加新字段,这个技巧将在你使用它的所有地方失败,这可能很难找到.
回答你的编辑:如果这是你的整个类定义,并且你正在使用一个带有默认选项的主流编译器,并在x86处理器上运行,那么是的,你可能已经猜到了正确的内存布局.但是,编译器,编译器选项和不同CPU架构的选择很容易使您的假设无效.
没有虚拟成员和没有继承的类在内存中布局就像结构一样.但是,当你开始获得继承级别时,事情会变得棘手,很难弄清楚内存中的顺序(特别是多重继承).
当你有虚拟成员时,它们在内存中有一个"vtable",它包含指向实际函数的指针,该函数是根据类的继承层次结构创建的.
底线是:如果你能避免它,就不要以这种方式访问类(也不要记住它们或记忆它们).如果你必须这样做(为什么?),那么请注意你确切知道你的类对象将如何在内存中,并小心避免继承.
| 归档时间: |
|
| 查看次数: |
14207 次 |
| 最近记录: |