C銷毀區域性變數的疑問

2022-05-31 01:42:08 字數 986 閱讀 8879

先說一下環境,vs2017,

下面的操作是定址呼叫子函式裡被釋放的int區域性變數的值並列印,

發現可以通過定址找到區域性變數被銷毀前的值,但是第二次定址發現值改變了。

c中的區域性變數在棧上分配空間,區域性變數作用域內,我們可以通過變數名找到對應的位址空間,讀寫變數

而「銷毀區域性變數」的具體操作是將區域性變數名(上圖的『a』)指向另外的區域,這樣我們編寫程式時如果想要通過使用a讀取那個位址空間儲存的值,會報錯,這就是銷毀的過程,

多次試驗,發現第二次定址輸出的值是int被初始化後的統一值 -858993460,也就是說在第一次讀取變數值之後,第二次讀取變數之前,原位址的值被初始化了,

那麼中間發生了什麼?

通過新增斷點可以看出,在第乙個printf之後,區域性變數位址儲存的值就被初始化了,

而如果將printf換成「 *int a=0;a++;」就不會導致初始化,

這說明,子函式的區域性變數被銷毀後,主函式後續執行的操作可能會導致初始化,也可能不會,

具體的解釋需要更底層的東西,之後學習了會更新……

銷毀的過程是指標重置,這樣節省開銷,但是有缺陷的,不安全的,這種定址會導致出現野指標,指標p就是野指標,

子函式定義的區域性變數在返回主函式,被銷毀之後,仍然可以通過p定址找到區域性變數的值,

但是這是未定義的行為,即不同的編譯器可以自行處理這種情況,上面的**在不同編譯器上可能執行結果不同,

子函式的區域性變數銷毀後,主函式的操作可能會導致原位址的值被初始化覆蓋,

另外,如果是主函式花括號內定義的區域性變數,

區域性變數的型別不是int、char等簡單型別,而是自己定義的結構體,

使用不同的編譯器,

那麼區域性變數銷毀後,原位址儲存的值是不確定的,可能不變,也可能被初始化,也可能隨機賦值,需要自己試驗,只是選了乙個示例進行記錄

valarha的回答

C 形參,區域性變數,靜態區域性變數區別

一.形參是一種自動物件,函式開始時為形參申請記憶體空間,呼叫函式時提供的實參初始化形參對應的自動物件 二.普通變數對應的自動自動物件,定義變數的語句出建立自動物件,所在塊結束,該變數也就結束 三.區域性靜態變數比較特殊,它的生命週期貫穿函式呼叫及之後的時間,區域性靜態變數對應的物件成為區域性靜態物件...

c 全域性變數 區域性變數

全域性變數即在函式外宣告的變數,區域性變數即在函式內部宣告的變數,例如 include float num 3.14 乙個名為num的全域性變數 void main float num 2.45 乙個名為num的區域性變數 cout3.14 當區域性變數和全域性變數同名時,在區域性變數作用域內使用該...

c 全域性變數,區域性變數

區域性變數又稱內部變數,是函式內部定義的變數,作用域在定義其的函式內部 全域性變數又稱外部變數,作用於是從其定義開始一直到源程式結束 不論是全域性變數還是區域性變數都是乙個空間上的範圍,即作用域 相對於變數的空間範圍,靜態和動態變數則指乙個時間上的範圍,所謂靜態變數就是在定義時分配固定儲存單元,知道...