C++ 类成员偏移地址不正确
我有一个问题,当我试图访问某个文件中某个类的成员时,它没有得到该成员的实际值。但当我尝试在其他地方访问它时,我会这样做 文件A:C++ 类成员偏移地址不正确,c++,gcc,assembly,compilation,C++,Gcc,Assembly,Compilation,我有一个问题,当我试图访问某个文件中某个类的成员时,它没有得到该成员的实际值。但当我尝试在其他地方访问它时,我会这样做 文件A: find_func_wrapper ( Func_Container * rules, char * func_name ) { ulong count = rules->function_count; cout << "A count: " << count << endl; B::find_func
find_func_wrapper ( Func_Container * rules, char * func_name ) {
ulong count = rules->function_count;
cout << "A count: " << count << endl;
B::find_func( rules, func_name );
}
main () {
Func_Container *rules = get_rules();
find_func_wrapper( rules, func_name );
}
当计数成员设置为2时。当我使用print rules->function\u count
时,在A和B中用gdb单步遍历代码,我得到2
在find_func_包装中反汇编代码
1885 ulong count = rules->function_count;
=> 0x0000000006004be5 <+294>: mov -0xa8(%rbp),%rax
0x0000000006004bec <+301>: mov 0x60a8(%rax),%rax
0x0000000006004bf3 <+308>: mov %rax,-0x38(%rbp)
打印规则和->函数\u计数的地址将返回与预期相同的地址。在我看来,罪魁祸首似乎在第二条mov
指令中,其中B中使用的偏移量0x60e8不正确。为什么会发生这种情况
get_rules()返回一个指向全局对象的指针,该对象在前面初始化并一直保留到程序结束
这是根据gcc 4.4.7进行编译的。这个项目非常大。此外,这只发生在调试版本中,发布版本或非优化版本似乎没有这个问题
Sizeof in find_func_wrapper: 24968
Offset: 3093
Sizeof in B::find_func: 25032
Offset: 3101
通过
(&rules->function\u count)-rules)计算的偏移量我能够缩小问题的来源,以便重新排列标题。将#include“Func_Container.h”
放在文件B中的其他include之前,我发现容器的大小正确。我继续在Func_Container
之前移动其他标题,直到找到导致问题的标题。我发现有问题的标题定义了\u GLIBCXX\u DEBUG
标志。这导致某些std类型中出现额外的调试成员,这些成员的大小发生了变化,所以当我在以后加载Func_容器的定义时,由于较大的类型,成员地址发生了变化
此邮件列表中提供了一个问题示例:这听起来似乎与对齐有关。通常,当您将类存储到文件时,您会在头之前指定对齐方式。在VisualStudio中,这类似于#pragma pack(1),确保两个TU共享相同的Func_容器定义
,并进行清理和重建。Visual Studio有时会出错并忘记重新编译对象文件。您确定两个文件都使用相同的标志编译吗?这听起来像func_容器可能有可选的ifdef字段。在这两个函数中打印sizeof(func_容器)。在重新安排一些事情之后,我发现这似乎是因为_GLIBCXX_DEBUG。B中包含的第一个标题定义了这一点。如果我包含Func_容器的标题,它将正常工作。我没有立即在Func#u容器的定义中看到任何依赖于此值的内容,但我不知道这会导致编译器执行什么操作。请添加您最后的注释作为答案,并提供更多详细信息,转发给下一个人。
1885 ulong count = rules->function_count;
=> 0x0000000006004be5 <+294>: mov -0xa8(%rbp),%rax
0x0000000006004bec <+301>: mov 0x60a8(%rax),%rax
0x0000000006004bf3 <+308>: mov %rax,-0x38(%rbp)
2652 ulong count = rules->function_count;
0x00000000062494a1 <+75>: mov -0x4f8(%rbp),%rax
0x00000000062494a8 <+82>: mov 0x60e8(%rax),%rax
0x00000000062494af <+89>: mov %rax,-0x50(%rbp)
Sizeof in find_func_wrapper: 24968
Offset: 3093
Sizeof in B::find_func: 25032
Offset: 3101