【发布时间】:2011-02-15 03:13:37
【问题描述】:
在 C(或 C++)中,如果指针的值为零,则它们是特殊的:建议我在释放内存后将指针设置为零,因为这意味着再次释放指针并不危险;当我调用 malloc 时,如果它无法获取内存,它会返回一个值为 0 的指针;我一直使用if (p != 0) 来确保传递的指针是有效的,等等。
但是既然内存寻址从 0 开始,那么 0 不就和其他地址一样是有效地址吗?如果是这种情况,如何使用 0 来处理空指针?为什么不是负数 null 而不是?
编辑:
一堆很好的答案。我将根据我自己的想法将其所表达的答案中所说的内容进行总结,并希望如果我有误解,社区会纠正我。
就像编程中的其他一切一样,它是一种抽象。只是一个常数,与地址 0 没有真正的关系。C++0x 通过添加关键字
nullptr来强调这一点。它甚至不是地址抽象,它是 C 标准指定的常量,编译器可以将其转换为其他数字,只要它确保它永远不会等于“真实”地址,并且等于其他 null如果 0 不是用于平台的最佳值,则为指针。
如果它不是一个抽象,就像早期的情况一样,地址 0 被系统使用,程序员不受限制。
-
我承认,我的负数建议有点疯狂。使用有符号整数表示地址有点浪费,如果这意味着除了空指针(-1 或其他)之外,值空间在构成有效地址的正整数和浪费的负数之间平均分配。
1234563或两位整数,即 [-2, 1]。但你可以选择 0 为空,1 为内存中唯一可访问的字节。)
我心中仍有一些未解决的问题。堆栈溢出问题 Pointer to a specific fixed address 告诉我,即使空指针的 0 是一种抽象,其他指针值也不一定。这导致我发布另一个堆栈溢出问题,Could I ever want to access the address zero?。
【问题讨论】:
-
您可以轻松地将
if (p != 0)更改为if (p),这是 C 和 C++ 中的常见习语,但如果您使用 Java,则必须改掉这个习惯。跨度> -
删除两次意味着您的代码错误。我建议不要在之后将指针设置为 null,这样您就可以崩溃并修复问题,而不是抑制它。在任何情况下,您都会错误地假设地址是某个整数。这不一定是真的,0 只是 表示 一些特定于实现的实际指针值。从概念上讲,“否定地址”没有意义。
-
@GMan:将指针设置为会导致崩溃的地址可能是个好主意,例如
0xDEADBEEF。 -
永不消亡的问题!
-
@Noah:点设置为null -> 隐藏编程错误,不要设置为null -> 查找编程错误。我不了解你,但我希望我的代码正确。