是否可以检查取消引用任意内存是否会使C中的apriori程序崩溃?

是否可以检查取消引用任意内存是否会使C中的apriori程序崩溃?,c,pointers,operating-system,C,Pointers,Operating System,我想编写一个交互式解释C shell,它允许您寻址任意内存并对这些内存地址执行命令 e、 g(运行程序外壳): 此指令将尝试访问地址0x400000并显示从那里开始的10个字节。e、 g.范围[0x400000,0x400009] 并将产生如下产出: {0x00, 0x01, 0x02, 0x03, 0x04, <bad>, <bad>, 0x07, 0x08, 0x09, 0x0a} {0x00、0x01、0x02、0x03、0x04、0x07、0x08、0x09、0

我想编写一个交互式解释C shell,它允许您寻址任意内存并对这些内存地址执行命令

e、 g(运行程序外壳):

此指令将尝试访问地址0x400000并显示从那里开始的10个字节。e、 g.范围[0x400000,0x400009]

并将产生如下产出:

{0x00, 0x01, 0x02, 0x03, 0x04, <bad>, <bad>, 0x07, 0x08, 0x09, 0x0a}
{0x00、0x01、0x02、0x03、0x04、0x07、0x08、0x09、0x0a}
其中“bad”表示试图寻址“非法”内存

我想知道C语言中是否有一种标准方法来检查程序是否允许访问我试图访问的内存,或者访问该内存是否会导致程序崩溃(在它实际崩溃之前),并向用户报告程序不允许访问该内存的信息

我这样问是因为关于这个主题的大多数问题的答案都是“你不能肯定地检查指针是否有效”,但我确信一定有某种方法来检查指针是否至少“肯定无效并将崩溃”或“可能无效,但不会崩溃”,不幸的是,我找不到这个问题的答案

提前谢谢

我想知道C语言中是否有一种标准方法来检查程序是否允许访问我试图访问的内存,或者访问该内存是否会导致程序崩溃(在它实际崩溃之前),并向用户报告程序不允许访问该内存的信息

不,没有

标准只规定不能取消对空指针的引用。除此之外,有效指针值的范围取决于平台。您希望实现的功能无法在平台无关代码中实现

根据C99标准中的脚注87:

一元*运算符取消引用指针的无效值包括空指针、与指向的对象类型不适当对齐的地址以及对象在其生命周期结束后的地址

我想知道C语言中是否有一种标准方法来检查程序是否允许访问我试图访问的内存,或者访问该内存是否会导致程序崩溃(在它实际崩溃之前),并向用户报告程序不允许访问该内存的信息

不,没有

标准只规定不能取消对空指针的引用。除此之外,有效指针值的范围取决于平台。您希望实现的功能无法在平台无关代码中实现

根据C99标准中的脚注87:

一元*运算符取消引用指针的无效值包括空指针、与指向的对象类型不适当对齐的地址以及对象在其生命周期结束后的地址


标准方式?不。你所经历的崩溃是未定义行为的结果。标准没有深入研究这些细节

Windows API提供了一个
IsBadReadPtr
函数,这似乎就是您想要的。答案很清楚,你不应该使用它

您忽略的是一些无效访问,您无法从中恢复。如果您触摸了一个保护页,并且在没有给保护页访问处理程序运行的机会的情况下捕获了错误,那么您就错过了机会。下次访问同一地址时,会出现访问冲突和核心转储。虽然在正常执行情况下,这也没问题。看

在Unix上,您可以让内核为您做一些不必要的工作。如果它返回
EFAULT
,则表示您的进程将崩溃

注意,虽然看起来你是在先验地检查,但实际上你是在检查后果。提前检查不可靠(检查和实际访问之间的映射可能会更改)

如果希望在失败后得到通知,请在UNIX上为
SIGSEGV
编写一个信号处理程序。在Windows上,处理
EXCEPTION\u ACCESS\u违规
SEH异常



附录:你想做的听起来有点像你做的。它将lua解释器注入到外部应用程序中,并允许调用和取消引用地址。如果你捏造它,只有重新启动的线程会受到影响,程序本身也会继续工作(至少有一段时间…)。该网站不再在线,但也许你成功地找到了一面镜子。

标准方式?不。你所经历的崩溃是未定义行为的结果。标准没有深入研究这些细节

Windows API提供了一个
IsBadReadPtr
函数,这似乎就是您想要的。答案很清楚,你不应该使用它

您忽略的是一些无效访问,您无法从中恢复。如果您触摸了一个保护页,并且在没有给保护页访问处理程序运行的机会的情况下捕获了错误,那么您就错过了机会。下次访问同一地址时,会出现访问冲突和核心转储。虽然在正常执行情况下,这也没问题。看

在Unix上,您可以让内核为您做一些不必要的工作。如果它返回
EFAULT
,则表示您的进程将崩溃

注意,虽然看起来你是在先验地检查,但实际上你是在检查后果。提前检查不可靠(检查和实际访问之间的映射可能会更改)

如果希望在失败后得到通知,请在UNIX上为
SIGSEGV
编写一个信号处理程序。在Windows上,处理
EXCEPTION\u ACCESS\u违规
SEH异常


附录:你想做的听起来有点像你做的。它将lua解释器注入到外部应用程序中,并允许调用和取消引用地址。如果你
{0x00, 0x01, 0x02, 0x03, 0x04, <bad>, <bad>, 0x07, 0x08, 0x09, 0x0a}
00400000-0040c000 r-xp 00000000 00:13 1237228                            /usr/bin/cat
0060b000-0060c000 r--p 0000b000 00:13 1237228                            /usr/bin/cat
0060c000-0060d000 rw-p 0000c000 00:13 1237228                            /usr/bin/cat
01864000-01885000 rw-p 00000000 00:00 0                                  [heap]
7fe7a5e0b000-7fe7a6121000 r--p 00000000 00:13 1487092                    /usr/lib/locale/locale-archive
7fe7a6123000-7fe7a62ba000 r-xp 00000000 00:13 1486770                    /usr/lib/libc-2.23.so
7fe7a62ba000-7fe7a64ba000 ---p 00197000 00:13 1486770                    /usr/lib/libc-2.23.so
7fe7a64ba000-7fe7a64be000 r--p 00197000 00:13 1486770                    /usr/lib/libc-2.23.so
7fe7a64be000-7fe7a64c0000 rw-p 0019b000 00:13 1486770                    /usr/lib/libc-2.23.so
7fe7a64c0000-7fe7a64c4000 rw-p 00000000 00:00 0 
7fe7a64cb000-7fe7a64ee000 r-xp 00000000 00:13 1486769                    /usr/lib/ld-2.23.so
7fe7a66cc000-7fe7a66ee000 rw-p 00000000 00:00 0 
7fe7a66ee000-7fe7a66ef000 r--p 00023000 00:13 1486769                    /usr/lib/ld-2.23.so
7fe7a66ef000-7fe7a66f0000 rw-p 00024000 00:13 1486769                    /usr/lib/ld-2.23.so
7fe7a66f0000-7fe7a66f1000 rw-p 00000000 00:00 0 
7fe7a66f5000-7fe7a66f8000 rw-p 00000000 00:00 0 
7ffe398e8000-7ffe39909000 rw-p 00000000 00:00 0                          [stack]
7ffe3999b000-7ffe3999e000 r--p 00000000 00:00 0                          [vvar]
7ffe3999e000-7ffe399a0000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
int main(void)
{
  unsigned long *p = 0xffffffffff600000;

  for (;;)
    printf("0x%lx, ", *p++);
}