【问题标题】:Unexpected Output from an Out-of-Scope Poiner范围外指针的意外输出
【发布时间】:2017-09-17 03:13:03
【问题描述】:

我最近遇到了一些 C++ 代码,我试图理解为什么输出不是我所期望的。这是有问题的代码:

char fun(char *p)
{
   char c = *p;
   (*p)++;
   return c;
}

int main()
{
    char arr[3]={'a', 'b', 'c'};
    fun(arr + 1);
    std::cout << fun(arr + 1);
    return 0;
}

这是我的大脑如何解析代码:

  1. fun() 的第一次调用将地址传递到arr 中存储“b”的位置

  2. fun() 内部,p 被取消引用,'b' 被分配给c

  3. p 再次被取消引用并递增为“c”

  4. 值'b'从fun()返回

这一点非常简单。

现在,第二次拨打fun() 时我遇到了麻烦。由于此时pc 都超出了范围,我假设对fun() 的第二次调用将产生完全相同的结果——明显的区别是返回值将打印到屏幕而不是比丢弃。但是,结果不是“b”,而是“c”——事实上,对fun(arr + 1) 的额外调用会在每次后续调用中进一步增加返回值到 d、e、f、g、h 等。

我知道即使在指针超出范围后该值仍存储在堆栈中,但我无法弄清楚即使在指针被销毁后该值似乎仍被引用。

【问题讨论】:

  • 您每次都将相同的地址传递给fun,因此每次该地址处的值都会递增,并返回之前的值。
  • 你所有的问题都没有实际意义。显示的代码是未定义的行为,&lt;&lt; 运算符可能会由于尝试打印非空终止字符串的内容而导致随机崩溃。
  • @SamVarshavchik 介意指出哪个部分(或行)是 UB?
  • 带有&lt;&lt; 运算符的那个。
  • @SamVarshavchik 没有尝试打印任何类型的字符串。 fun 返回单个字符,而不是您误读的 char *,因此应该明确定义,尽管它并没有像 OP 想象的那样。

标签: c++ pointers scope


【解决方案1】:

(*p)++;

p 引用 arr [1]。

每次执行此操作时,都会增加 arr [1] 中的值。第一次是“b”,第二次是“c”,依此类推。

【讨论】:

  • 谢谢!在发布这个问题之前,我已经尝试在fun() 中添加一个cout &lt;&lt; &amp;p,并且已经注意到每次都传递了相同的地址。我基本上忘记了增量运算符的基本原则之一,因为它实际上是将增量值分配给增量变量,而不仅仅是增加值。通过将此行更改为*p = *p + 1;,我可以很容易地看到发生了什么。
猜你喜欢
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 2017-09-30
  • 1970-01-01
  • 1970-01-01
  • 2013-10-24
相关资源
最近更新 更多