我正在学习C++并阅读C++ Primer.有一个问题我想知道答案:
给定指针p,您可以确定p是否指向有效对象?如果是这样,怎么样?如果没有,为什么不呢?
谢谢.
Ker*_* SB 36
不,你不能.为什么?因为维护关于什么构成有效指针以及什么不构成的元数据是昂贵的,并且在C++中你不支付你不想要的东西.
并且您不想检查指针是否有效,因为您知道指针的来源,或者因为它是您控制的代码的私有部分,或者是因为您在面向外部的合同中指定了它.
Mah*_*esh 12
不可能.想想这个场景.
int *ptr = new int(10);
int *ptrDup = ptr;
delete ptr;
Run Code Online (Sandbox Code Playgroud)
但ptrDup仍然指向ptr不再存在的内存位置.因此,引用ptrDup结果未定义的行为.但是参考计数完全是一个不同的概念.
不太可能看到指针是否在所有含义中都是"有效的".
当然,您可以尝试取消引用指针(*ptr = x;或x = *ptr).如果您的代码没有崩溃,则指针指向有效内存.如果它崩溃了,显然,指针是不好的.不幸的是,这种方法有点像检查枪是否被装在头上 - 这不是最聪明的......不幸的是,有了指针,没有"检查腔室是否装满",所以没有真正好的方法来确定指针是否有效,除了"如果它不会导致硬件故障,它是有效的".
请注意,在大多数情况下,这只会告诉您"指针指向您可以访问的某些内存".这并不意味着指针"对于您想要的是正确的"(例如,它指向正确的类型).并且它只是不会告诉你指针是否指向"陈旧数据"(也就是说,当指针WAS有效时,但它现在用于其他东西的内存).
不幸的是,在现代系统中,有2 32或2 64 [实际上是2 48 ]可能有效的存储器地址,几乎不可能知道哪些地址有效,哪些地址不有效.即使在操作系统内部,操作系统如果能够写入您要求它写入的内存,也会"尝试写入,看看会发生什么".对于操作系统,这很好,因为它可以小心"这可能会出错,如果确实如此,我将继续在那里的错误恢复代码".操作系统必须处理这个问题,因为它必须接受,a)程序员犯错误,以及b)有些人实际上将恶意代码写入TRY以破坏操作系统.
应用程序"确保指针有效"的方式是程序员编写关于它存储在指针中的内容,如何释放这些指针以及仅使用存储在其中的有效值的指针的代码.你最终不应该"检查指针是否有效" - 然后你"做错了".
(当你使用系统一段时间,并在调试器中读取指针值时,你会在一段时间后识别出"好"和"坏"指针 - 但这只是因为你通常会学到一个好的指针与一个好的指针编写代码以识别这种情况几乎是不可能的 - 特别是如果系统分配了大量内存,那么它会占用大部分可用空间.)
当然,在C++中,有智能指针,向量和各种其他工具,这意味着很多时候你甚至不必费心去指针.但是理解如何使用指针以及指针如何工作仍然是一件好事.