有人可以帮我弄清楚为什么" next"我的链表中的指针在32位平台上的代码中取消引用错误的内存地址,但在64位平台上工作正常吗?我的程序在Xcode 7.3上构建为通用二进制文件,用C ++编写。
我有一个链接列表,并且取消引用了" next"调试器中的指针显示正确的内存,但在代码中取消引用它会读取超出应该读取的4字节的内存。我会尝试解释..
列表中的对象各为4144个字节,最后4个字节是指向" next"的32位指针。列表中的项目。看着"下一个"指针在内存中(0xBFFD63AC),我们看到它是4个零(NULL),这是正确的。但请注意,0xBFFD63B0处的内存为0x01。这是" next"之后的字节。指针。当我要求调试器打印下一个变量时,它会输出正确的值(NULL):
(lldb) print l_pObject->Next
(Object__t *) $0 = 0x00000000
(lldb) memory read &(l_pObject->Next)
0xbffd63ac: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
但是,如果我执行解除引用" next"指针,它实际上从0xBFFD63B0而不是0xBFFD63AC读取数据:
l_pObject = l_pObject->Next;
(lldb) print l_pObject
(Object_t *) $3 = 0x00000001
(lldb) memory read &(l_pObject)
0xbffd2504: 01 00 00 00 80 53 fd bf 00 00 00 00 6c 82 2e
我很肯定它是从0xBFFD63B0读取0x01。调试器似乎知道" next"表示内存为0xBFFD63AC,但出于某种原因解除引用" next"在代码中实际上从0xBFFD63B0读取,但我不知道如何找出原因。我已经尝试将__attribute__((packed))
添加到结构中,但这没有任何区别。很难确定出错的地方,因为调试器告诉我一些与实际情况不同的东西。如何从这里开始的任何提示将非常感谢!
已编辑添加更多信息:
至少在这里有调试器错误!我要求调试器打印结构的大小,它给了我4144,但在代码中我使用C函数sizeof(),这给了我4148!所以在结构中肯定会出现填充,但调试器显然这部分代码对它是盲目的。这是我问题的根源。
调试器:
(lldb) print sizeof(*l_pObject)
(无符号长)$ 0 = 4144
代码:
unsigned int iSizeOf = sizeof(*l_pObject); /* iSizeOf will equal 4148! */
有趣的事情正在发生......
答案 0 :(得分:0)
没有看到代码就无法分辨。一般来说,指针往往在64位系统上为8字节宽,在32位系统上为4位宽。很明显,你发现它超出了它应该的4个字节,这是一个强有力的指标。 (0xBFFD63B0 - 0xBFFD63AC) == 4
。
答案 1 :(得分:0)
好的,我发现了问题,我应该马上意识到这一点。崩溃的代码在库中。库和调用应用程序共享变量类型的定义。由于应用程序端缺少预处理程序标志,其中一个类型在应用程序端比在库代码中分配小4个字节。因此,当应用程序创建对象的链接列表并传递对库的引用时,该列表上的每个对象都比库期望的小4个字节。让它变得不那么明显的是,调试器根据应用程序中分配的内容向我显示了地址和偏移量,因此乍一看,所有内容的大小都是正确的。我决定不信任调试器并编写自己的代码来检查地址和偏移量,而且当它变得明显发生了什么时。所以,无论如何,长话短说,请确保您的应用程序和库分配类型相同的大小,然后事情会更好。 :)