2011-09-19 53 views
3

我玩C++在VisualStudio2010分配指向未初始化變量的指針會改變它的值嗎?

請解釋爲什麼會發生:

int a, b; 
int *p, *q; 
cout << a << " " << b; 

打印出 「0」。這是可以理解的,未初始化的整數應該是0; 但

int a, b; 
int *p, *q; 
p = &a; 
cout << a << " " << b; 

輸出爲「1792816880 0」

所以,如果我給你的指針從默認初始化的變量它的變化值。 爲什麼?

編輯澄清:問題不是關於未初始化的變量

int a; int *p; 
cout << a; // would be 0, because it's loacal variable 
p = &a; 
cout << a; //not 0; 

價值如何得到的一個指針可以改變它的價值?當我們初始化變量時,我們分配空間,有些位,它們可能是任何東西,但是「p = & a」它實際上是否改變了這個空間中的位?

+0

有趣。在Fedora 15 x64_86的G ++ 4.6.0下也會出現類似的情況。 – trojanfoe

+2

增加項目設置中的警告級別。這將檢測未初始化變量的用法。 – Stephan

+0

不是。 未初始化的整數應參照本地變量 –

回答

6

那麼它是可以理解的,未初始化的整數應該是0

有沒有這樣的保證,它取決於存儲類,如果你的int是局部變量它有一個自動存儲並且不必爲0.

訪問單元化變量導致未定義行爲和您的代碼導致未定義的Beh avior。一旦出現未定義行爲,所有投注都將停止,並且行爲無法解釋。

關於未定義行爲,

C++標準部1.3.24狀態:

允許不確定的行爲的範圍從具有不可預知的結果完全無視的情況下,在一個或翻譯程序執行期間表現有記錄的環境特徵(有或者沒有發佈診斷消息),終止翻譯或執行(通過發佈診斷消息)。

編輯:
鑑於上述情況,這是不確定的行爲與一個人不應該寫依賴於這種行爲的任何代碼,事實上一個也別想寫這樣的代碼。我發現它無關緊要地深入到所有這些編譯器的實現中,以此來解釋它爲什麼會起作用。

如果有人發現此回覆頭重腳輕,您可以自由下注。如果downvote計數超過upvotes,我會知道答案是不受歡迎的,我會刪除它。

+0

+1。 –

+0

我不認爲「未定義行爲的防守回答了這個問題確實它是0 – trojanfoe

+2

@trojanfoe這是唯一可能的答案。程序的行爲是不確定的,所以幾乎可能發生任何事情。 –

2

沒有定義未初始化值的值。沒有默認值。任何價值都可能出現。

你可以改變這些垃圾軟件就會給你一個答案,你的不定值的查詢的潛在價值的任何看似無關的操作。

底線是,不要推測應該發生什麼未定義的行爲。這是簡單的未定義 - 不要寫未定義行爲的代碼。

3

這是C++中的「未定義行爲」。

當你不用C++初始化一個變量時,它並不總是爲零。這只是偶然。內存被分配,並且之前在該內存位置中的垃圾值將被輸出,直到它被初始化。

0

C++不會初始化聲明變量,它只是爲它們分配RAM內存。如果你使用指針或者不使用指針,它們可以在初始化之前使用任何值。 您應該始終在使用前初始化您的變量。

+0

RAM?這些變量都存儲在堆棧中! – trojanfoe

+0

@trojanfoe:你說堆棧不是RAM? – Stephan

+0

當然沒有,但它的分配方式並不一樣。 – trojanfoe

0

在C++中,未初始化的本地整數不保證爲0。他們是「垃圾」,因此,他們可以是包括0

2

這是不確定的行爲,但這裏是一些炒作,以什麼可能發生的任何值:

在第一個代碼示例,該變量的地址是從來沒有被採納過,因此編譯器選擇將它們保存在寄存器中並且它們永遠不會存在於主存儲器中,並且寄存器的值恰好爲0.

在第二個代碼示例中,在內存中(在堆棧上),以便它可以有一個地址。恰巧現有的數據存在一些隨機垃圾。

1

你有一堆沒有寫入的變量,永遠。編譯器可能決定不爲這些變量分配存儲空間。這可能看起來很苛刻,但這是合理的:現代編譯器在細粒度級別上分配變量存儲,並且某些分支上可能未使用某些變量。當不需要時爲什麼要分配內存?

現在,如果您從未分配內存的「變量」讀取數據會發生什麼,因爲您從未寫入過內存?你會得到一些隨機數據,很可能是另一個變量。或者是段錯誤 - 未定義行爲有很多種形式。

現在拿你的第二個例子:在這裏你寫入一個變量,p。由於a不需要任何內存分配(沒有寫入),所以它可能很好地別名p。和p值,重新解釋爲int很可能是1792816880.

相關問題