2015-04-17 38 views
0

我總是想知道爲什麼存儲在內存空間中的垃圾值。爲什麼內存不能充滿零。有特別的原因嗎?爲什麼內存位置分配了垃圾值?

例如:

int a ; 
cout<<a //garbage value displayed 
+0

@MarcGlisse開導我 –

+0

你應該閱讀[這個答案](http://stackoverflow.com/a/1422774/4516316)on [未初始化變量如何獲得垃圾值?](http://stackoverflow.com/questions/1422729/how-an-uninitialised-variable-gets-a-garbage-value) –

回答

7

分配零需要時間,並不總是程序員想要做的事情。考慮到這一點:

int a; 
std::cin >> a; 

爲什麼當你要做的第一件事是在那裏存儲一個不同的值時,浪費時間加載一個零到內存中?

+0

但是,存儲垃圾值不同嗎? –

+2

@MohitBhasi號垃圾在那裏,因爲*沒有*做過,所以內存包含任何已發生的隨機值。 – Galik

1

現代操作系統做初始化的內存爲0的過程之前,首先獲取訪問它。但是一旦它被使用過了,除非有特殊的需求,否則通常不會再將其清零。 「垃圾值」就是上次寫入該內存的內容。

+0

爲了說明,請嘗試「static int a; cout << a;」。 – user3344003

+0

C++中有完全定義好的行爲(因爲我懷疑你知道) - 但是需要初始化變量。沒有'static',它變得更有趣。 –

+0

是的,說明你的原點。 – user3344003

1

因爲清除內存很昂貴(或者確實是),並且在大量的常見情況下並不需要它。

在示例中,您將顯示堆棧內存。每次將其清零(基本上每個函數調用都必須清除一塊內存)將會非常昂貴。

1

對於(主要是歷史)性能的原因。將以後分配適當值的內存位置歸零是不必要的工作,而c/C++口號之一是「您不需要支付您不需要的東西」。

通常你應該總是正確地初始化一個變量,當它被聲明的時候,但是特別是在c中,你有時候還不知道,變量的初始值應該是什麼。

編輯:如果您的問題是關於垃圾數據來自何處:它只是以前存儲在同一物理地址的數據。比方說,你是直接陸續致電以下兩個功能:

void foo(){ 
    int a=5; 
} 
void foo2() { 
    int b; 
    std::cout << b << std::endl; 
} 

int main() { 
    foo1(); 
    foo2(); 
} 

這是相當有可能的,這(在調試模式)程序的輸出將是5(我認爲,這實際上是UB,所以 - 考慮到編譯器優化 - 當然會發生任何事情)

+2

我不會說它是歷史的... –

+0

@KarolyHorvath:它當然還是有它的好處的,但是現在有很少的實例(與c相比),你不能在聲明點正確地初始化一個變量,在這種情況下(如作者的例子),在大多數系統上初始化本地變量的成本實際上並不那麼大。如果C++是今天設計的,並且不需要向後兼容,我想他們會在許多方面做出不同的決定。 – MikeMB

+0

同樣在某些情況下(即使在c)中,會發生不必要的零初始化,編譯器可能會證明該位置僅在寫入後才被讀取,因此可以在這些情況下默認丟棄初始化。 – MikeMB

0

您得到的垃圾值是先前存儲在該地址中的值。但在C++(和許多其他語言)中,將它們全部初始化爲零是編譯器無法完成的昂貴任務。這會浪費很多時間,編譯器可能用於其他目的。所以,分配新值不是由編譯器完成的。

但還有其他編譯器將它們初始化爲0,但C++不是其中之一。

正常情況下,編譯器會期望您爲新變量賦予一個新值。像

int a = 0; // this is not so hard to do 

int a; 
std::cin >> a ; 

所以,我們分配一個值遠高於編譯器更有效的初始化,然後將其覆蓋。

如果你在訪問它們之前沒有賦值,編譯器會給你一個關於未初始化變量的警告。 (如果您打開了編譯器警告)。

0

垃圾值來自內存空間中的內容。在你的情況下,你只聲明瞭變量並沒有初始化它。當一個變量被聲明並且未被初始化時,內存被分配給該變量但不被清除,主要是出於性能原因。因此,它可能包含您不希望它包含的初始值,這可能由於以下原因而發生。根據Code Complete第10章,一些原因包括:

  • 該變量從來沒有被賦值。它的價值在於程序啓動時內存區域發生的任何事情。
  • 變量中的值已過時。變量在某個點被分配了一個值,但該值不再有效。
  • 部分變量已被賦值並且部分沒有(具體涉及可能有多個數據成員的對象)。

一個好的做法是在聲明和初始化儘可能接近的地方他們第一次使用,即通過使相關的動作在一起按照就近的原則的變量。