2017-09-17 68 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