2012-10-17 28 views
1

這必須是一個愚蠢的問題,但我無法理解爲什麼會這樣解引用preincremented指針給奇結果

int main() 
{ 
    int i=20; 
    int *p=&i; 
    cout<<"old p="<<p<<endl; 
    *(++p) = 10; 
    cout<<"p="<<p<<endl; 

} 

在這段代碼中,我得到的輸出: 老P = 0x22ff08 p = oxa

爲什麼指針的值變爲10(0xa)而不是遞增前面的地址並將10賦值給該位置?

+3

*是*未定義的行爲。 – chris

+1

你是什麼意思「增加早先的地址和分配10到那個位置」?你期望的結果是什麼? –

+0

我的想法是,指針變量可能指向新的位置0x22ff0C,並嘗試在那裏輸入值。但現在我明白了。感謝R.Martinho。謝謝你們。 – sajas

回答

4

爲什麼指針的值變爲10(0xa)而不是遞增前面的地址並將10賦值給該位置?

去哪個地點? 有沒有這樣的位置p指向一個int,而不是一排int s。這種增量所產生的指針並不指向您可以執行間接尋址的位置。試圖這樣做,因爲此代碼確實有未定義的行爲,這意味着絕對會發生任何事情。編譯器可以隨心所欲地做任何事情,因爲對需要發生的事情沒有要求。不要這樣做。

在您的特定實驗中,出現這兩個變量分別位於彼此相鄰,並且當遞增,可變p結束了指向其自身,然後分配10,這是一個十六進制的。當您使用不同的編譯器版本或編譯器選項編譯時,或者即使您對代碼做出看似無害的更改,也無法保證這會再次發生。不要這樣做。

+0

看一看。我使用了兩個不同版本的相同編譯器,並得到了兩個不同的結果:http://ideone.com/eTnOD和http://liveworkspace.org/code/20bde3a566de683718bf122ef699e7f3。這不僅僅是獲得不同產出的問題。事實上,使用第一個,程序*崩潰*與分段錯誤(看看它說的「結果:運行時錯誤(SIGSEGV)」) –

+0

我現在有一個ideone的替代品。隨着最新版本的GCC和Boost。謝謝。 –

1

您正試圖通過遞增指針來訪問可能已被其他程序/進程佔用或正在使用的位置,並且您試圖覆蓋該值。

1

通過將指針遞增一個元素,實際上您正在訪問相同的指針並將其值修改爲0xA,因爲它們位於內存中。