【问题标题】:Why are two integer pointers of the same value point to the same thing (via ==) ?为什么相同值的两个整数指针指向同一事物(通过 ==)?
【发布时间】:2013-10-11 19:47:54
【问题描述】:
int *x = 3;
int *y = 3;

if (x == y) "this statement evaluates to true" (pointer equality statement)
if (*x == *y) "this statement evaluates to true"

是不是指针相等语句变为真的原因,仅仅是因为编译器看到两个“静态”数字“3”并说,嘿指向同一个地方?或者一般整数有什么魔力。

很明显,引用一个整数指针(在这种情况下)与不取消引用是一样的。

我已经看到了一些与字符串有关的问题示例 (Addresses of two pointers are same),但想进一步澄清它。

【问题讨论】:

  • 你使用了什么编译器和选项
  • 当您取消引用 x 时,您正在查看内存地址“3”。你很幸运此时没有出现段错误。
  • “仅仅因为编译器看到了两个“静态”数字“3”,然后说,嘿把这个指向同一个地方吗? - 不。无需为此进行优化即可按原样运行。只是常识。
  • @abelenky 倒霉。
  • 如果您强制操作系统将 I/O 端口、硬件寄存器甚至共享内存映射到内存空间的地址 3,则映射内存的连续读取可能不会返回相同的值。但是,如果您进行这种映射,您需要将指针声明为 volatile 以防止编译器优化读取。

标签: c pointers integer


【解决方案1】:
int *x = 3;

这是无效的(违反约束),并且符合要求的编译器需要发出诊断,并且可以完全拒绝它。不能使用整数值来初始化指针(0 的特殊情况除外,它是 空指针常量)。

如果编译器碰巧接受它,它将可能将其视为等同于:

int *x = (int*)3;

这会导致指针x 指向内存中的地址3。这几乎可以肯定是荒谬的。

鉴于xy 使用相同的表达式进行初始化(并且假设您的代码没有被拒绝),x == y 为真一点也不奇怪。

取消引用x 具有未定义的行为; (int*)3 很可能不是有效地址,因为它超出了程序的合法寻址空间和/或因为它未对齐。但是如果 *x 恰好“工作”并产生一个值,*x == *y 是真的也就不足为奇了。编译器可能识别出x == y,因此得出结论*x == *y。您可以通过检查生成的代码来确定这一点。但这真的没关系;一旦您的程序的行为未定义,则任何事情都可能发生(或者更确切地说,语言标准允许任何事情发生;物理定律可能对此有其他说法)。

您应该已经收到两个声明的警告。如果你这样做了,你应该注意它。如果没有,您应该了解如何提高编译器的警告级别。

【讨论】:

  • 谢谢你,我实际上并没有亲自测试这个,而是在我的课堂上提出了这个逻辑并且一直困扰着我。通常当我对某事感到困惑时,一开始似乎总是有问题,所以似乎又是这样。我想老师试图提出的观点是指针“变量”地址(&x 和 &y)与指针实际指向的地址之间存在差异。我实际上认为他呈现的方式意味着指针获得值“3”。 Annnnnd 那是我开始怀疑我的知识的地方
  • @anon:对,问题是3 不是指针值。例如,使用(int*)0xdeadbeef 的示例虽然明确表明这只是一个示例,不一定是有效地址,但可能更清楚地说明了这一点。人们普遍认为整数和指针“真的”是同一件事,但恕我直言,最好保持概念不同。
【解决方案2】:

您只是硬编码了两个指针的固定内存地址3。按理说,这个简单的地址是相同的,并且无论数据实际上是 AT 那个地址也将是相同的。

这就像你的冰箱上有两张便签。两者都说“钥匙在逐个桌子上”。天哪,当你走到门口时,你的钥匙就在那儿。两个不同的指针,都指向同一个东西。

【讨论】:

  • 您假设int *x = 3; 等价于int *x = (int*)3;。目前尚不清楚这是否属实。无论如何,这是违反约束的。
【解决方案3】:

两者的声明

int *x = 3;
int *y = 3;

是违反约束的。你可以声明

int *x = (int *)3;
int *y = (int *)3;

这两个都指的是内存的地址3。

if (*x == *y) "this statement evaluates to true"  

没有。它调用未定义的行为。你可能会得到任何东西。这将评估为 truefalse

【讨论】:

  • 这个答案看起来并没有真正回答问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-21
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-17
  • 2013-10-08
相关资源
最近更新 更多