在C语言中,指针能够指向自己的内存地址吗?

4
在以下代码中,指针指向自己的内存地址。
#include <stdio.h>

int main() 
{
    void * ptr;
    ptr = &ptr;

    return 0;
}

如果指针能够指向自己的内存地址,这是否有意义?


你会期望错误或警告说什么?也就是说,这里有什么(甚至可能的)问题? - Scott Hunter
我猜这应该归为“有点奇怪,但如果你坚持要做,也没问题”的类别。 - Martin James
4个回答

7
不,这没有意义。如果您可以找到变量ptr,则只需执行&ptr。它将给出与ptr的内容相同的结果。
此外,由于ptr仅告诉有关自身的信息,因此无论如何都是无用的。它不提供任何对程序其余部分有意义的信息。
想想看,有一个例外情况。您可以使用ptr == &ptr的情况作为一种特殊值,例如NULL。因此,在这种情况下,我认为它是有用的。
有趣的是,在这种情况下,&ptr的值作为特殊值是有意义的,而作为某物的地址则没有意义,就像NULL一样。

很遗憾,在几乎所有情况下,您无法进行ptr == &ptr比较,因为类型将不同,必须进行转换。 - cmaster - reinstate monica
是的,我会为此编写一个带有引用参数的模板函数...但这并不高效。另一方面,拥有不止一个而是两个特殊值本身就很了不起。 - Jacques de Hooge
这种方式有什么不如“ptr = ptr”更不合理的地方吗? - Scott Hunter
@ScottHunter:我认为你的例子无法比较,因为 void * ptr = ptr; 是不合法的。 - alk
@ScottHunter:假设ptr是一个带有副作用重载=运算符的对象(开玩笑)。 - Jacques de Hooge
显示剩余7条评论

5

指针指向自己的内存地址。

这是合法的。

它是否“有意义”完全取决于上下文和“主要是可选的”思考方式。


2

从法律上讲,这是合法的C语言分配。但问题是用于什么目的。我认为这只是学术考虑,没有任何实际用途。


3
并非所有合法的事情都是有意义的......例如,我可以在我的汽车上粘壁纸。 - Jacques de Hooge
同意@PeterJ的观点。 - kocica
1
@PeterJ 我读了它,但对我来说,“讲得通”意味着“有目的”。 - Jacques de Hooge
从完整语句中取出的单词被称为操作。我已经清楚地写明它没有任何实际用途。 - 0___________
不要太认真了,你的意思已经很清楚和正确了!我只是吹毛求疵,因为我还没有吃早餐! - Jacques de Hooge
如上所述,只是挑剔一点。 - Jacques de Hooge

-3

还有一个尚未提及的方面是,它违反了严格类型检查。
如果ptr的类型为void *,那么&ptr的类型就是void **,由于类型不匹配(void *void **),不能将其赋值给ptr
然而,当涉及到指针类型时,C和C++通常非常宽松,每当一个void *被赋值时,因为void *应该能够指向任何东西。
但是假设您实际上想要正确地取消引用ptr,则您需要在分配后像这样执行:

*(void **)ptr = ...

假设您实际上想要在某个时刻取消引用它。


1
在 C 语言中,void 指针没有严格类型限制,因此不存在这样的规则。在 C 语言中,从任何其他指针类型到 void 指针或者从 void 指针到任何其他指针类型的转换都是合法的。但在 C++ 中,这种转换是不被允许的。 - alk
实际上这已经包含在我的帖子中了,但是不遵守严格的类型规定仍然是不好的风格,因此我认为值得一提。 - iolo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接