有人能帮我弄清楚为什么我的链表中的“下一个”指针在 32 位平台上取消引用代码中的错误内存地址,但在 64 位平台上工作正常吗?我的程序是在 Xcode 7.3 上构建为通用二进制文件并用 C++ 编写的。
我有一个链表,在调试器中取消引用“下一个”指针会显示正确的内存,但在代码中取消引用它会读取超出应读取位置 4 个字节的内存。我会尽力解释..
列表中的每个对象都是 4144 字节,最后 4 个字节是指向列表中“下一个”项目的 32 位指针。查看内存中的“下一个”指针(0xBFFD63AC),我们看到它是 4 个零(NULL),这是正确的。但请注意 0xBFFD63B0 处的内存是 0x01。这是超出“下一个”指针的字节。当我要求调试器打印下一个变量时,它打印出正确的值 (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 ................
但是,如果我执行取消引用“下一个”指针的代码,它实际上从 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))
添加到结构中,但这没有任何区别。很难确定问题出在哪里,因为调试器告诉我一些与实际发生的事情不同的事情。非常感谢有关如何从这里开始的任何提示!
编辑以添加更多信息:
至少这里有一个调试器错误!我要求调试器打印结构的 sizeof,它给了我 4144,但在代码中我使用了 C 函数 sizeof(),它给了我 4148!所以结构中肯定发生了填充,但调试器和显然这部分代码对它视而不见。这是我问题的根源。
调试器:
(lldb) print sizeof(*l_pObject)
(无符号长)$0 = 4144
代码:
unsigned int iSizeOf = sizeof(*l_pObject); /* iSizeOf will equal 4148! */
有趣的事情正在发生......
最佳答案
不看代码就无法分辨。但一般来说,指针在 64 位系统上往往是 8 字节宽,在 32 位系统上往往是 4 位宽。显然,您观察到它超出了应有的位置跳跃了 4 个字节,这是一个强有力的指标。 (0xBFFD63B0 - 0xBFFD63AC) == 4
。
关于c++ - 为什么我的链表 "next"指针解引用到错误的内存(XCode,C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36879798/