众所周知,访问无效内存会导致段故障,从而导致系统崩溃。我希望在系统崩溃之前知道内存是否无效。
答案 0 :(得分:2)
这是特定于Linux的,但实现简单可靠。
打开/proc/self/maps
。它是一个文本伪文件,列出了当前进程的所有内存映射。它在man 5 proc中描述;请参阅/proc/[pid]/maps
部分。这些线看起来像
7fb5cb179000-7fb5cb32e000 r-xp 00000000 fc:00 14651 /lib/x86_64-linux-gnu/libc-2.15.so
但是你只需要用十六进制解析起始地址十六进制到破折号-
,结束地址(不包括;它是地图外的第一个地址),十六进制直到空格{{1和一些模式字母直到下一个空格。
模式字母表示映射可读,
r
可写,w
可执行,x
共享,s
私有。 (将来可能还有其他字母,所以最好忽略除了那些和空格p
之外的所有字母。)
因为是C中最大的标准整数类型,所以应该使用
long
作为地址(包括解析它们时)。您还可以使用unsigned long
将任何指针转换为地址。使用(unsigned long)pointer
只能在大多数64位Linux体系结构上运行,因为它往往是32位,因此无法表示所有指针。
如果指针地址在所有这些地图之外,则保证无效:取消引用指针会给你一个分段错误。
如果指针位于上述地图之一内,则地图模式描述哪些操作有效,以及它是什么类型的地图。如果您知道指针旨在指向数据,则您知道目标映射不应该是可执行的,例如。
在多线程程序中,您将希望尝试立即将整个文件读入内存,以便您可以看到内存映射的一致快照,然后使用字符串操作解析数据。如果您发现没有读取完整文件,只需重新读取该文件即可。您应该使用int
中的低级I / O(而不是使用unistd.h
或stdio.h
中的函数)来执行此操作,以避免任何缓存和抽象。实际上,我也推荐这个程序用于单线程应用程序;这是一种强有力的方法。
答案 1 :(得分:1)
简短的回答是没有便携,可靠的方法。
100%正确且应该如此。你问的是“如何让我的程序检测到我的程序中有错误?” - 唯一可以获得无效指针的方法是,如果你有一个错误(或者只是编写错误的代码)。
使用valgrind或类似方法分析代码并修复导致内存访问不良的任何错误的想法是最佳解决方案。
答案 2 :(得分:0)
有趣的话题。请在此处查看讨论:http://www.cplusplus.com/forum/beginner/49550/
Microsoft为此提供了一个函数:IsBadReadPtr(http://msdn.microsoft.com/en-us/library/aa366781(VS.85).aspx)
我找不到类似Linux的东西。但是,您可以在valgrind(http://valgrind.org/)中运行程序以检测无效的指针引用。
答案 3 :(得分:0)
在现代多用户操作系统上,无效的内存访问不会导致系统崩溃 - 它只会使导致无效访问的程序崩溃。