簡體   English   中英

垃圾值如何分配給c中的變量

[英]How garbage values are assigned to variables in c

C代碼:

int a;
printf("\n\t %d",a); // It'll print some garbage value;

那么這些垃圾值是如何分配給 C 中幕后未初始化的變量的呢?

這是否意味着C首先將內存分配給變量'a',然后該內存位置的任何內容都變成'a'的值? 或者是其他東西?

這是否意味着C首先將內存分配給變量'a',然后該內存位置的任何內容都變成'a'的值?

確切地!

基本上,C 不會做任何你不告訴它的事情。 這既是它的強項,也是它的弱點。

這是否意味着C首先將內存分配給變量'a',然后該內存位置的任何內容都變成'a'的值? 或者是其他東西?

正確的。 值得一提的是,像int a這樣的自動變量的“分配”實際上是不存在的,因為這些變量存儲在堆棧或 CPU 寄存器中。 對於存儲在堆棧中的變量,在調用函數時會執行“分配”,歸結為將堆棧指針移動編譯時計算的固定偏移量的指令(函數使用的所有局部變量的組合存儲,四舍五入到正確對齊)。

分配給 CPU 寄存器的變量的初始值是寄存器以前的內容。 由於這種差異(寄存器與內存),有時會發生在沒有優化的情況下編譯時正常工作的程序在打開優化的情況下編譯時會開始中斷。 未初始化的變量,以前指向碰巧被零初始化的位置,現在包含以前使用相同寄存器的值。

最初內存有一些值,那些是未知值,也稱為垃圾值,當我們聲明一個變量時,根據我們在聲明時指定的數據類型為變量保留一些內存,所以內存初始值是未知值,如果我們初始化其他一些值,那么我們的值將在那個內存位置。

int a ;

聲明變量時,分配內存。 但是這個變量沒有被賦值,這意味着變量a沒有被初始化。 如果這個變量a只被聲明但在程序中不再使用,則稱為垃圾值 例如:

int a, b;

b=10;
printf("%d",b);
return 0;

在這里它只被聲明但不再分配或初始化。 所以這叫做垃圾值

這是否意味着C首先將內存分配給變量'a',然后該內存位置的任何內容都變成'a'的值?

不,不是那個意思。

當一個對象未​​初始化時,C 標准不提供任何關於如何確定其值的計划。 不僅如此,程序不需要表現得好像對象具有任何固定值。 它可以變化,就好像為它保留的內存沒有保持在任何固定狀態,只是波動。

以下是關於此的特定 C 2018 規則:

  • 未初始化對象的所謂“值”是不確定的,根據 6.2.4 6 用於沒有可變長度數組類型的自動存儲持續時間的對象,6.2.4 7 用於具有可變長度數組類型的對象,7.22.3.4 2 用於分配的對象使用malloc , 7.22.3.5 2 用於realloc分配的額外空間, 7.22.3.1 2 用於aligned_alloc 初始化其他對象,例如具有靜態存儲持續時間的對象。
  • 根據 3.19.2,不確定值是“未指定的值或陷阱表示”。
  • 根據 3.19.3,未指定值是“相關類型的有效值,其中本文檔對在任何情況下選擇哪個值沒有要求”。

這意味着在每個實例中使用一個對象,C 標准對使用哪個值沒有任何要求。 它不需要與以前的使用相同。 程序可能表現得好像它沒有任何固定值。 當它被多次使用時,程序可能會表現得好像每次都具有不同的值。 例如,C 標准將允許printf("%d %d %d\n", a, a, a); 打印“34 -10200773 2147483204”。

可能發生這種情況的一種方法是,在嘗試編譯代碼時int a; printf("%d %d %d\n", a, a, a); int a; printf("%d %d %d\n", a, a, a); ,編譯器無處可取,因為它從未被a任何固定值。 因此,編譯器不會生成無用的指令來將數據從未初始化的內存移動到傳遞參數的位置,而是不會生成任何內容。 然后調用printf ,傳遞參數的寄存器或堆棧位置包含它們之前的任何數據。 這很可能是printf打印的三個不同的值。 所以它看起來輸出的觀察者好像aprintf("%d %d %d\n", a, a, a);中有三個不同的值。 .

(此外,使用具有自動存儲持續時間且尚未獲取其地址的未初始化對象的值是明確未定義的行為,因為 6.3.2.1 2,關於將對象轉換為其值,說“如果左值指定一個對象可以使用寄存器存儲類聲明的自動存儲持續時間(從未獲取其地址),並且該對象未初始化(未使用初始化程序聲明並且在使用之前未對其進行分配),行為未定義。 ” 所以,當有一個對象滿足這些條件時,使用它的值可以完全破壞程序;它可能不僅在不同的時間有不同的值,而且程序可能會中止,走一個與你預期不同的分支,而不是調用printf當源代碼中有printf時,以此類推。)

我幾年前調查過的是:

答案是垃圾值是前一個程序的剩余部分。

因此,當您運行任何使用變量存儲值的程序時,當它結束時,操作系統只會釋放內存並使其可用於其他程序,但操作系統不會自動刷新這些位置的數據。

因此,當您聲明一個未初始化的變量時,OS 會將任何可用內存分配給該變量,並且由於您沒有分配任何值,因此該位置上的剩余值不會被覆蓋,而是成為該變量的 GARBAGE VALUE,因為它不相關。

這也可以用一個小程序通過使用指針訪問先前程序中變量的位置來證明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM