C 是否可以确定指针是否指向有效对象?

新手上路,请多包涵

我正在学习 C++ 并阅读 C++ Primer。有个问题想知道答案:

给定一个指针 p ,你能确定 p 是否指向一个有效的对象吗?如果是这样,怎么做?如果不是,为什么不呢?

原文由 2013Asker 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 726
2 个回答

不,你不能。为什么?因为维护有关什么构成有效指针和什么不是有效指针的元数据会很昂贵,而且在 C++ 中,您无需为不想要的内容付费。

而且您 不想 检查指针是否有效,因为您 知道 指针的来源,或者因为它是您控制的代码的私有部分,或者因为您在面向外部的合同中指定了它。

原文由 Kerrek SB 发布,翻译遵循 CC BY-SA 3.0 许可协议

真的不可能看到一个指针是否在所有含义上都是“有效的”。

当然,您可以尝试取消引用指针( *ptr = x;x = *ptr )。如果您的代码没有崩溃,则指针指向有效内存。如果它崩溃了,显然,指针不好。不幸的是,这种方法有点像通过向你的头部射击来检查枪支是否装载 - 这不是最聪明的……不幸的是,使用指针,没有“检查腔室以查看它是否装载”,所以除了“如果它不会导致硬件故障,它是有效的”之外,没有真正的好方法来确定 a 指针是否有效。

请注意,在大多数情况下,这只会真正告诉您“指针指向您可以访问的某些内存”。这并不意味着指针“对于您想要的它是正确的”(例如,它指向正确的类型)。而且它肯定不会告诉您指针是否指向“陈旧数据”(即,当指针有效时,但它现在是用于其他用途的内存)。

不幸的是,在现代系统中有 2 32或 2 64 [实际上是 2 48 ] 可能有效的内存地址,几乎不可能知道哪些地址是有效的,哪些是无效的。即使在操作系统内部,操作系统确定它是否可以写入您要求它写入的内存的方式是“尝试写入它,看看会发生什么”。对于操作系统来说,这很好,因为它可以小心“这可能会出错,如果出错,我会在错误恢复代码中继续那里”。操作系统必须处理这个问题,因为它必须接受 a) 程序员犯错误,以及 b) 有些人实际上编写了恶意代码来尝试破坏操作系统。

应用程序“确保指针有效”的方法是程序员编写代码时要小心它在指针中存储的内容,如何释放这些指针,并且只使用其中存储了有效值的指针。你不应该最终“不得不检查指针是否有效”——那么你就是“做错了”。

(当您使用系统一段时间并在调试器中读取指针值时,您会在一段时间后识别“好”和“坏”指针 - 但这只是因为您了解通常情况下好的指针与坏指针看起来像。编写代码来识别这种情况几乎是不可能的 - 特别是如果系统分配了大量内存,因此它使用了大部分可用空间。)

当然,在 C++ 中,有智能指针、向量和各种其他工具,这意味着很多时候您甚至不必为指针操心。但是了解如何使用指针以及指针如何工作仍然是一件好事。

原文由 Mats Petersson 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏