我們知道,當控件退出函數時,堆棧空間將被釋放。那麼靜態變量會發生什麼。它們會被保存在任何內存中,並在函數被調用時被檢索?如何獲取每個函數調用的靜態變量
3
A
回答
3
的wiki說:
在C語言編程,靜態使用全局變量 和功能在其範圍設置爲包含文件。在本地 變量中,靜態用於將變量存儲在靜態分配的內存中,而不是自動分配的內存中。 雖然 語言沒有規定任一類型的 存儲器的實現,靜態分配的存儲器通常在數據在編譯時保留 段的程序,而自動 分配的存儲器作爲瞬時調用堆棧通常實現。
和
靜態局部變量:雖然具有相同的範圍內自動 局部變量聲明爲靜態函數 內部變量是靜態分配的。因此,當再次調用 函數時,函數在一次調用期間將靜態局部變量放入其 的任何值仍將存在。
3
1
您做了一個錯誤的假設,即static
變量放置在堆棧上*當使用它們的函數正在運行時,所以需要保存和檢索它們。
這不是C如何做的:靜態變量被分配在堆棧外的完全不同的內存段中,所以當函數結束其自動變量的作用域時,它們不會被釋放。
通常,靜態數據段在進入程序時被創建並初始化一次。之後,只要您的程序正在運行,段就會保持分配狀態。所有的全局變量以及來自所有函數的靜態變量都由編譯器放置在該段中。這就是爲什麼進入或離開功能對這些變量沒有影響。
*「堆棧」的正式名稱是「自動存儲區域」。
3
添加預先給予答案的頂部一些更多的信息 -
存儲靜態對象在編譯/鏈接時被分配。他們的地址由鏈接器根據鏈接器控制文件修復。
鏈接器文件定義了物理存儲器佈局(Flash/SRAM)和不同程序區域的放置。
靜態區域實際上又細分爲兩個其他部分,一個用於初始值,另一個用於運行時間所做的更改。
最後,請記住,如果您不另行指定,編譯期間該值將被設置爲0。
0
考慮這個例子:
static int foo;
void f(void)
{
static int bar;
}
唯一的區別和之間FOO欄是FOO具有文件作用域而酒吧具有功能範圍。這兩個變量都存在於程序的整個生命週期中。
相關問題
- 1. 編譯器如何知道每個靜態變量調用一次函數?
- 2. 從靜態函數獲取靜態變量C++
- 3. WCF靜態變量通過每次調用獲取重置
- 4. 如何從另一個靜態函數調用靜態函數
- 5. 如何從靜態函數中獲取/設置成員變量?
- 6. 靜態函數中的靜態變量?
- 7. 從靜態函數調用非靜態變量
- 8. 家長靜態函數調用靜態子變量
- 9. 非靜態變量和靜態函數調用jsp
- 10. jQuery如何替換函數中的每個循環動態的靜態變量
- 11. 如何保護靜態函數/變量
- 12. 靜態函數和非靜態變量
- 13. 如何寫一個使用靜態變量的遞歸函數
- 14. 靜態變量和函數
- 15. 全局靜態變量vs函數中的靜態變量?
- 16. 如何從靜態回調函數中獲取對象引用?
- 17. 如何爲動態「每個」功能使用靜態變量?
- 18. 靜態變量和函數的用法
- 19. 通過調用另一個函數設置的函數中的靜態變量
- 20. 獲取變量來調用函數C++
- 21. 在函數中使用靜態變量()
- 22. 獲取類的靜態成員變量
- 23. 調用兩次靜態變量的函數?
- 24. 聲明靜態變量在C++中的函數調用
- 25. 如何獲取每個登錄用戶的靜態對象?
- 26. 如何獲取函數的變量
- 27. C++回調函數,在靜態函數中調用成員變量
- 28. 靜態成員變量可以調用非靜態成員函數嗎?
- 29. 如何在內聯函數中聲明一個靜態變量?
- 30. PHP:引用靜態變量中的另一個靜態變量
謝謝你拉胡爾。所以靜態變量在編譯時獲得內存分配,對嗎? –
感謝您強調實施不是由該語言指定的。 – phoxis
@seereddisekhar在運行可執行文件時,它們實際上並沒有在編譯時進行分配,因此加載程序會根據可執行文件中指定的內容來調整內存中的可執行文件。因此,實際分配將在加載時發生,但編譯規範時,將定義相對地址和偏移量。 – phoxis