【发布时间】:2016-07-13 21:53:15
【问题描述】:
我想编写一个交互式解释 C shell,它允许您寻址任意内存并在这些内存地址上执行命令。
例如(运行程序外壳):
prompt> 10 bytes starting 0x400000
该指令将尝试访问地址 0x400000 并显示从那里开始的 10 个字节。例如范围 [0x400000, 0x400009]。
并会产生如下输出:
{0x00, 0x01, 0x02, 0x03, 0x04, <bad>, <bad>, 0x07, 0x08, 0x09, 0x0a}
“坏”表示尝试寻址“非法”内存。
我想知道 C 中是否有标准方法来检查程序是否被允许访问我试图访问的内存,或者访问该内存是否会导致程序崩溃(在它实际崩溃之前),并向用户报告不允许程序访问该内存的信息。
我问这个是因为关于这个主题的大多数问题都倾向于通过“你不能肯定地检查指针是否有效”来回答,但我确信必须有某种方法来检查指针是否至少是“绝对无效,会崩溃”或“可能无效,但不会崩溃”,很遗憾我找不到这个问题的答案。
提前谢谢。
【问题讨论】:
-
除非您已经访问过内存,否则您将如何查看是否可以访问内存?不,您无法检查指针是否有效;您可以检查它是否为 NULL,但您无法判断它指向的位置是有效内存。它可能看起来是一个有效的地址,而只是一个随机值。我认为回答“不,你不能那样做”的不是大多数问题,而是所有问题。如果您找到了一个不这么说的人,那么您已经得到了问题的答案。
-
我不在乎它是否有效,我在乎它是否会使程序崩溃。我不介意破坏内存或访问我尚未分配的内存,我只关心它是否可以访问。
-
什至什么。这是您的硬件架构和操作系统的问题,而不是 C。该语言只能编译为前实体在运行时允许或拒绝的机器代码。诸如是否允许任意编号的地址之类的问题恰恰与 C 无关。此外,仅尝试访问编号地址的行为并不是定义的行为,更像是实现定义的充其量。对于大多数平台来说,指针是用来指向对象的,而不是特定的地址,而 C 认为后者只是一个必要的偶然事件。
-
我在第一句话中提到了这一点。你可以像调试器那样做,但是如何做这个问题在这里太宽泛了。有关于编写调试器的书籍,并且已经有很多调试器可用(包括许多免费的)。
-
所以检查内存是否合法的唯一方法是通过系统调用(依赖于平台)如果这样的调用首先存在?我真的不想相信这是这种情况,因为程序被告知了它映射到的地址以及它的虚拟地址空间之外的信息,我不明白为什么这些信息不可用C.
标签: c pointers operating-system