考虑以下C ++类:
class MyClass
{
TypeA a;
TypeB b;
TypeC c;
};
我使用的编译器以这样的方式创建此类的表示,即内存中成员的顺序与我在类定义中使用的顺序相同。我最近遇到了一个程序,利用这个事实来初始化成员。我知道这是一个非常糟糕的主意,因为布局取决于编译器,但我没有编写代码,它到目前为止工作。
我想知道现代操作系统中的ASLR
功能是否会弄乱这一点。如果对象在heap
上动态实例化,我很确定不是这种情况。但其他情况呢?
答案 0 :(得分:3)
否......标准保证了内存布局中的顺序,尽管成员之间也可以有填充(总是包含在sizeof
结果中,但这确实意味着你所描述的hacky代码可能想使用显式的pragma打包数据成员或使用offsetof来计算要操作的偏移范围,否则它们可能会在布局不同的其他编译器/编译器设置中断。
另外,无论创建这些对象的位置如何,对象的布局都是相同的:globals,stack,heap - 它总是相同的。考虑 - offsetof是编译时常量。