C中全局變量和static變量的存儲與初始化

目標(biāo)文件缨叫、可執(zhí)行程序及其他二進(jìn)制文件以ELF格式存儲在磁盤中,該文件有兩個重要的段(section)荔燎,即代碼段和數(shù)據(jù)段耻姥。
數(shù)據(jù)段又分為:.data 段 和 .bss段,其中.data段存儲已初始化的全局變量和靜態(tài)變量湖雹,.bss 段存儲未初始化的全局變量咏闪。

在C中,凡是在任何代碼塊之外聲明的變量總是存儲于靜態(tài)內(nèi)存中摔吏,也就是不屬于堆棧的內(nèi)存鸽嫂,這類變量稱為靜態(tài)(static)變量≌鹘玻——C和指針(p43)

這句話中有兩個概念需要搞清楚:

  • 靜態(tài)內(nèi)存:指的是前文所述的數(shù)據(jù)段(.data 段 和 .bss段)据某,不包括堆棧。
  • 靜態(tài)(static)變量:沒有static關(guān)鍵字的變量也可以是靜態(tài)變量诗箍,關(guān)鍵是存儲于靜態(tài)內(nèi)存中癣籽。實際上,當(dāng)static關(guān)鍵字用于不同上下文環(huán)境時,具有不同的意思筷狼。
    同時瓶籽,我們還知道,靜態(tài)變量在程序運行之前被創(chuàng)建埂材,其分為兩種:已初始化的 和 未初始化的塑顺。
    • 已初始化的包括:static變量 (這里不能稱其為靜態(tài)變量)、 已初始化的全局變量俏险;static變量是默認(rèn)zero-initialization的严拒,所以就算未顯示初始化,也會被zero-initialization竖独; 全局變量 <=字面值(或常量)裤唠,即賦予字面值時會在編譯階段就被初始化,如:int g_var = 4莹痢;
    • 未初始化的:即未初始化的全局變量种蘸。
      如前文所述,前者存儲于.data段竞膳,后者存儲于.bss段劈彪。且前者的初始化是在編譯階段就完成的,后者的初始化時刻不一定顶猜,我們在后文中討論。但兩者的共同點是痘括,都是在運行前創(chuàng)建的长窄。

這時,我們也許想問纲菌,運行前是如何創(chuàng)建靜態(tài)變量的?

我們知道挠日,編譯-匯編后生成二進(jìn)制目標(biāo)文件(ELF格式),雖然還不是最終的可執(zhí)行文件翰舌,但已經(jīng)有了代碼段和數(shù)據(jù)段嚣潜,而此時數(shù)據(jù)段中的.data段中已經(jīng)有了‘已初始化的靜態(tài)變量’的磁盤存儲空間,并被填充了初始化值椅贱,在進(jìn)程加載時直接被映射至內(nèi)存空間中懂算。

而.bss段實際上未占據(jù)任何磁盤存儲空間,也就是徒有其名庇麦,無有其實计技,只是在ELF的section header table 中記錄其應(yīng)該分配到的磁盤存儲空間,而直到可執(zhí)行程序被加載到內(nèi)存中時山橄,加載器將依據(jù).bss段的section header中的信息垮媒,在內(nèi)存中為其分配空間。

總結(jié)來說就是,運行前創(chuàng)建分為兩種:編譯時創(chuàng)建——>加載時映射至內(nèi)存睡雇;加載時創(chuàng)建萌衬。


此時,我們?nèi)杂幸苫笏Вo態(tài)變量的創(chuàng)建肯定是在運行前了秕豫,那么未初始化變量的初始化到底是在什么時候進(jìn)行的?

有三個猜測:

  • 鏈接時抗愁?前文中講馁蒂,直至進(jìn)程加載至內(nèi)存時才分配空間,自然無談初始化蜘腌。
  • 加載進(jìn)程至內(nèi)存時

(C和指針)在靜態(tài)變量的初始化中沫屡,我們可以把可執(zhí)行文件想要初始化的值放在當(dāng)程序執(zhí)行時變量將會使用的位置(注:實際上就是磁盤文件.data 段),當(dāng)可執(zhí)行文件載入到內(nèi)存時撮珠,這個已經(jīng)保存了正確初始值的位置將賦值給那個變量……如果不顯式地指定其初始值沮脖,靜態(tài)變量將初始化為0。

這段話說的比較晦澀芯急,因為它不想引入過多程序裝載過程的知識勺届。但我們也可以借此判斷,未初始化的全局變量實際上和static一樣會被初始化為0娶耍,只不過它是在可執(zhí)行文件載入到內(nèi)存時發(fā)生的免姿。

  • 運行時,所謂運行時初始化榕酒,即動態(tài)初始化(dynamic-initialization)胚膊,然而C與C++不同,靜態(tài)變量不支持動態(tài)初始化想鹰。所以運行時也是不可能的紊婉。
//in C
int x = 5;
static y = x; //error

//in C++
int x = 5;
static y = x; //correct

最終總結(jié):
在C中,靜態(tài)變量辑舷,即全局變量和static變量喻犁,是在程序運行前創(chuàng)建的,其中已初始化的全局變量和static變量在編譯匯編成目標(biāo)文件時何缓,初始值就已經(jīng)保存在磁盤的.data段了肢础,進(jìn)程加載時將其映射到內(nèi)存空間即可;
未初始化的全局變量需要進(jìn)程加載時真正的為.bss段分配內(nèi)存空間碌廓,并賦值為0乔妈。靜態(tài)變量的創(chuàng)建和初始化都是在運行前完成的,切記C中不能動態(tài)初始化氓皱,這一點與C++不同路召。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勃刨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子股淡,更是在濱河造成了極大的恐慌身隐,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唯灵,死亡現(xiàn)場離奇詭異贾铝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)埠帕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門垢揩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人敛瓷,你說我怎么就攤上這事叁巨。” “怎么了呐籽?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵锋勺,是天一觀的道長敛助。 經(jīng)常有香客問我豁辉,道長,這世上最難降的妖魔是什么童擎? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任贪惹,我火速辦了婚禮苏章,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奏瞬。我一直安慰自己布近,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布丝格。 她就那樣靜靜地躺著,像睡著了一般棵譬。 火紅的嫁衣襯著肌膚如雪显蝌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天订咸,我揣著相機(jī)與錄音曼尊,去河邊找鬼。 笑死脏嚷,一個胖子當(dāng)著我的面吹牛骆撇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播父叙,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼神郊,長吁一口氣:“原來是場噩夢啊……” “哼肴裙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起涌乳,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蜻懦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后夕晓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宛乃,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年蒸辆,在試婚紗的時候發(fā)現(xiàn)自己被綠了征炼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡躬贡,死狀恐怖谆奥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情逗宜,我是刑警寧澤雄右,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站纺讲,受9級特大地震影響擂仍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜熬甚,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一逢渔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乡括,春花似錦肃廓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至敷扫,卻和暖如春哀蘑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背葵第。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工绘迁, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卒密。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓缀台,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哮奇。 傳聞我的和親對象是個殘疾皇子膛腐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容