我正在
*** glibc检测到***(/ my / program / ...):malloc():内存损坏:0xf28000fa ***
我在valgrind下运行,它报告了已经释放的读取内存的情况,但没有非法内存写入的情况。
读取释放的内存会导致内存损坏吗?如果没有,除了valgrind输出之外还有哪些建议?
答案 0 :(得分:5)
您可以使用GDB观察此内存地址中的每次写入,如下所示:
(gdb) watch *((int*)0xf28000fa)
然后你可以调试问题所在。
阅读不会导致内存损坏,但是有很多情况你甚至都没想到可能是造成这种情况的原因,而Valgrind并不是一个完美的工具。
查看有关调试内存问题的更多信息here。
答案 1 :(得分:2)
它不会破坏您阅读的内存,但它不会为您的程序运行带来奇迹。
答案 2 :(得分:1)
读取释放的内存也被视为内存损坏。
答案 3 :(得分:1)
不,读取无效位置不可能导致您看到的错误。如果该位置在您的地址空间中有效,您将只是阅读垃圾,否则,您将收到分段错误。
检查valgrind的输出以查看无效读取的来源 - 这将为您提供真正错误所在位置的提示。一旦你发现了这一点,我很确定真正的罪魁祸首不会很远,这可能是一个无效的写作。
答案 4 :(得分:1)
在当前的处理器上应该不常见,但我已经在甚至读取操作都能发挥魔力的平台上工作过。在特定的6502处理器中映射了I / O,因此带有I / O映射地址的常规“读”指令可以做出令人惊讶的事情。
大约30年前,我被这种感觉所困扰,因为我的错误读取引起了存储库开关(即存储器的每个字节,包括包含代码的区域,在该指令之后获得了新的不同值)。 有趣的是,这不是一个真正的“无意识的”糟糕的阅读......即使知道它会变成垃圾,我实际上也会阅读,因为这为我节省了一些汇编指令......不是一个聪明的举动。
答案 5 :(得分:0)
真正发生的是,free可以使用madvise(MADV_DONTNEED)系统调用来告诉内核“我不需要这个页面,放弃它”(参见madvise(2)manpage)。如果该页面真的被释放并且您从中读取了任何内容,则内核将默默地提供新的页面,将其清零 - 从而导致您的应用程序遇到完全意外的数据!