2017-09-17 46 views
-1

我最近遇到了一些C++代码,我想了解为什么输出不是我所期望的。这是有问题的代码:超出范围Poiner的意外输出

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()第一个电话将地址传递到“B”存储在arr

  2. 内部fun()p被derefernced和 'b' 被分配给c

  3. p再次解除引用和递增到 'C'

  4. 值 'b' 可从fun()

非常简单返回到这一点。

现在,第二个电话fun()是我遇到麻烦的地方。由于pc在这一点已经超出了范围,我假设第二次调用fun()将产生完全相同的结果 - 显而易见的区别是返回值将被打印到屏幕而不是被丢弃。但是,不是'b',结果是'c' - 实际上,对于每个后续调用,额外调用fun(arr + 1)会将返回值进一步增加到d,e,f,g,h等等。

我明白,即使在指针超出范围之后,该值仍然存储在堆栈中,但我无法弄清楚即使在指针被销毁后,值仍然看起来被引用。

+0

您每次都将相同的地址传递给'fun',因此每次都会增加该地址的值,并返回前一个值。 – Charles

+2

你所有的问题都是没有意义的。显示的代码是未定义的行为,由于试图打印非空终止字符串的内容,“<<”运算符可能导致随机崩溃。 –

+0

@SamVarshavchik介意指出哪部分(或行)是UB? – Charles

回答

1

(* p)++;

p引用arr [1]。

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

+0

谢谢!在发布这个问题之前,我已经尝试在fun()中添加'cout <<&p',并且已经注意到每次都传递相同的地址。我基本上忘记了增量运算符的基本原理之一,因为它实际上将递增的值分配给递增的变量,而不仅仅是递增值。通过将此行更改为'* p = * p + 1;',我能够很容易地看到发生了什么。 – michaelgfunk