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