无效*读取*释放的内存会导致内存损坏吗?
我收到
*** glibc检测到***(/my/program/...):malloc():内存损坏:0xf28000fa***
我在valgrind下运行,它报告读取<的情况/em> 内存已被释放,但没有非法内存写入的情况。
读取释放的内存会导致内存损坏吗?如果没有,除了 valgrind 输出之外,还有什么建议可以查看吗?
I'm getting
*** glibc detected *** (/my/program/...): malloc(): memory corruption: 0xf28000fa ***
I've run under valgrind, which reports cases of reading memory that has been freed, but no cases of illegal memory writes.
Could reading freed memory cause memory corruption? If not, any suggestions where else to look beyond the valgrind output?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
真正发生的情况是,free 可以使用 madvise(MADV_DONTNEED) 系统调用来告诉内核“我不需要这个页面,删除它”(请参阅 madvise(2) 手册页)。如果该页面确实被释放并且您从中读取了任何内容,内核将默默地提供新的页面,清零 - 从而导致您的应用程序遇到完全意外的数据!
What can really happen, is that free can use madvise(MADV_DONTNEED) syscall to tell the kernel "I don't need this page, drop it" (see madvise(2) manpage). If that page gets really deallocated and you read anything from it, kernel will silently provide freshly new page, zeroed out - and thus cause your application to encounter completely unexpected data!
您可以使用 GDB 来观察该内存地址中的每次写入,如下所示:
然后您可以调试问题出在哪里。
读取不会导致内存损坏,但有很多情况你甚至无法想象可能会导致这种情况,而且 Valgrind 并不是一个完美的工具。
请在此处查看有关调试内存问题的更多信息。
You can use GDB to watch each write in this memory address, like this:
Then you can debug where the problem is.
Reading doesn't cause memory corruption, but there are a lot of situations that you don't even imagine that could be the cause of this, and Valgrind is not a perfect tool.
See more information about debugging memory issues here.
它不会破坏你读取的内存,但也不会对你的程序的运行产生奇迹。
It won't corrupt the memory you read, but it isn't going to do wonders for the working of your program.
读取释放的内存也被视为内存损坏。
您还可以查看http://en.wikipedia.org/wiki/Memory_corruption。
Reading freed memory is also considered memory corruption.
You can also check http://en.wikipedia.org/wiki/Memory_corruption.
不,读取无效位置不可能导致您看到的错误。如果该位置在您的地址空间中有效,您将只是读取垃圾,如果不是,您将遇到分段错误。
检查 valgrind 的输出以查看无效读取的来源 - 这将为您提供真正错误所在的提示。一旦你找到了这个,我很确定真正的罪魁祸首就在不远的地方,而且很可能是无效的写入。
No, reading invalid locations can't possibly cause the error you are seeing. If the location is valid in your address space, you'll just be reading junk, if not, you'll get a segmentation fault.
Check valgrind's output to see where the invalid reads are coming from - this will give you a hint towards where the real mistake lies. Once you find this, I'm quite sure the real culprit won't be far away, and it's probably an invalid write.
这在当前的处理器上不应该那么常见,但我曾经在一些平台上工作过,即使是读取操作也可以发挥神奇作用。在特定的 6502 处理器中,具有映射 I/O,因此具有 I/O 映射地址的常规“读”指令可以执行令人惊讶的操作。
大约 30 年前,我被这个问题困扰,因为我的错误读取引发了内存库切换(即内存的每个字节,包括包含代码的区域,在该指令之后立即获得了一个新的不同值)。
有趣的是,这并不是真正的“无意”的糟糕阅读……即使知道它会是垃圾,我实际上还是进行了阅读,因为这为我节省了一些汇编指令……这不是明智之举。
It shouldn't be that common on current processors, but I've worked on platforms where even a read operation could do magic. In the specific 6502 processor has mapped I/O, so a regular "read" instruction with a I/O mapped address can do surprising stuff.
About 30 years ago I got bitten by that because my bad read provoked a memory bank switch (that is every byte of memory, including the area containing the code, got a new different value just after that instruction).
The funny part is that it wasn't a truly "unintentional" bad read... I actually did the read even if knowing that it was going to be garbage because this saved me a few assembler instructions... not a smart move.