C++局部靜態變數的內存什麼時候創建的?
局部靜態變數的存儲空間創建時間,是在程序運行時就創建,還是說等到第一次執行到該靜態變數的時候才創建然後初始化的。
目前只清楚,局部靜態變數是保持在程序的全局/靜態存儲區,初始化是在第一次執行時處理,但創建卻不明白。煩請懂得知友解答一下!謝謝!
C++11:內存地址早就佔用了,但是會在你第一次執行到初始化的那行代碼的時候初始化它,線程安全,可重入。
在Windows和Linux平台,全局/靜態存儲區跟執行代碼一樣,是在編譯過程中就已經生成在執行文件中。在執行文件被載入(比如執行a.exe或a.out)時,由操作系統直接映射到內存中。
所以,你的問題的答案是「是在程序運行時就創建」。
有興趣可以找一些PE和ELF文件格式,以及操作系統如何載入執行文件的資料看看具體是醬紫的局部靜態跟全局靜態內存中性質一樣,文件里都在數據段。唯一區別局部靜態變數有作用域限制,是靠編譯器幫忙語法檢測。局部靜態變數有個初始化問題,當多次調用一個含有局部靜態變數的函數時候,怎麼保持之初始化一次。
程序會在內存中第一個bit位,來標識是否初始化過。
所以答案是,該局部靜態變數跟全局變數一樣很早就存在於全局數據區。但當第一次運行到該函數,會檢測一個位,來判斷是否已經初始化。參考書籍,c++反彙編與逆向分析技術揭秘靜態局部對象:在程序執行到該對象的定義處時,創建對象並調用相應的構造函數!
如果在定義對象時沒有提供初始指,則會暗中調用默認構造函數,如果沒有默認構造函數,則自動初始化為0。
如果在定義對象時提供了初始值,則會暗中調用類型匹配的帶參的構造函數(包括拷貝構造函數),如果沒有定義這樣的構造函數,編譯器可能報錯!直到main()結束後才會調用析構函數!轉自:《高質量程序設計指南》贊同 @vczh和 @Pluto Hades的答案。
可以再參考 初始化、顯式初始化、隱式初始化。這幾個區別是什麼? - 編程語言 的回答。
這裡補充說明幾點,來自《Working Draft, Standard for Programming Language C++》:
The keyword static can be used to declare a local variable with static storage duration. The static storage shall last for the duration of the program.
The zero-initialization of all block-scope variables with static storage duration is performed before any other initialization takes place. Constant initialization of a block-scope entity with static storage duration, if applicable, is performed before its block is first entered.
Such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration.
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
Destructors for initialized objects (that is, objects whose lifetime has begun) with static storage duration are called as a result of returning from main and as a result of calling std::exit.
推薦閱讀:
※C++允許「我們都是人,所以我可以把你私有的眼睛借來隨便玩,再還給你」,這難道是一種設計上的妥協?
※visual studio和gdb的調試機制到底是怎麼樣的?
※C++不用工具,如何檢測內存泄漏?
※生物信息學需要掌握C++嗎?
※如何實現一個C++反射庫?