C++內(nèi)存管理

內(nèi)存布局

????? C++的內(nèi)存分為5大區(qū),按照地址從高位到低位的順序殉摔,分別為棧區(qū)州胳,堆區(qū),BBS區(qū)逸月,數(shù)據(jù)區(qū)栓撞,代碼區(qū)。

棧區(qū)

???? 編譯器自動(dòng)管理分配碗硬,存放程序中的局部變量瓤湘,函數(shù)參數(shù)值,返回變量恩尾。內(nèi)存分配從高地址向低地址增長(zhǎng)弛说。

堆區(qū)

???? 程序中用戶自定義動(dòng)態(tài)分配的內(nèi)存區(qū)域,內(nèi)存分配從低地址向高地址增長(zhǎng)翰意。

BBS區(qū)

???? 存放程序中被顯示初始化為0的全局變量和靜態(tài)變量剃浇;以及未被初始化的全局變量和靜態(tài)變量。

數(shù)據(jù)區(qū)

???? 存放已初始化的全局變量猎物,靜態(tài)變量虎囚,常量數(shù)據(jù)(如字符串常量)。

代碼區(qū)

???? 存放可執(zhí)行程序的機(jī)器碼蔫磨。

下圖是內(nèi)存布局的基本結(jié)構(gòu)

C++內(nèi)存布局

函數(shù)棧

?????? 如上圖所示淘讥,可執(zhí)行程序文件包含BBS,數(shù)據(jù)區(qū)和代碼區(qū)堤如,可執(zhí)行程序載入內(nèi)存后系統(tǒng)會(huì)保留一些空間蒲列,堆區(qū)和棧區(qū)。堆區(qū)主要是動(dòng)態(tài)分配的內(nèi)存(默認(rèn)情況下)搀罢,而棧區(qū)主要是函數(shù)以及局部變量等蝗岖。

當(dāng)調(diào)用函數(shù)時(shí),一塊連續(xù)內(nèi)存壓入棧榔至;函數(shù)返回時(shí)抵赢,堆棧幀彈出。

堆棧幀包含如下數(shù)據(jù):

1).函數(shù)返回地址

2).局部變量/CPU寄存器數(shù)據(jù)備份

以main調(diào)用fa(),fa調(diào)用fb(),來舉例說明函數(shù)調(diào)用壓棧過程唧取,如下圖所示:

調(diào)用進(jìn)棧

函數(shù)調(diào)用結(jié)束后會(huì)依次出棧铅鲤,如下圖所示:

出棧

全局變量

????? 當(dāng)全局變量,靜態(tài)變量未被初始化的時(shí)候枫弟,他們記錄在BBS段邢享。

?????? 處于BBS段的變量值默認(rèn)為0,考慮到這一點(diǎn)淡诗,BBS段內(nèi)部無需存儲(chǔ)大量的零值骇塘,只需記錄字節(jié)個(gè)數(shù)即可伊履。BBS段主要是為了節(jié)省可執(zhí)行文件在磁盤上所占空間,它只記錄變量所需的大小款违。對(duì)未初始化的大型數(shù)組的節(jié)省效率比較明顯唐瀑,舉例如下:

d

在上述程序中,若不存在BBS段奠货,可執(zhí)行文件將開辟10000*sizeof(int)大小的空間,并全部存儲(chǔ)為0座掘,該變量將在磁盤上占用39KB的空間递惋,但是若存在BBS段,則在可執(zhí)行文件中溢陪,將只是記錄現(xiàn)在BBS段總大小40000即可萍虽,無需占據(jù)39KB的空間。

系統(tǒng)載入可執(zhí)行程序后形真,將BBS段的數(shù)據(jù)載入數(shù)據(jù)段杉编,并將內(nèi)存初始化為0,再調(diào)用程序入口main函數(shù)咆霜。

內(nèi)存對(duì)齊

? ? ? 對(duì)于基本類型邓馒,如float,double蛾坯,int光酣,char等,他們的大小和內(nèi)存占用是一致的脉课。但是對(duì)于結(jié)構(gòu)體而言救军,我們?nèi)〉闷鋝izeof的結(jié)果,會(huì)發(fā)現(xiàn)這個(gè)值可能會(huì)大于結(jié)構(gòu)體成員大小的總和倘零,這是由于結(jié)構(gòu)體內(nèi)部成員進(jìn)行了內(nèi)存對(duì)齊唱遭。

???? 進(jìn)行內(nèi)存對(duì)齊有2個(gè)好處:

??? 1).內(nèi)存對(duì)齊使數(shù)據(jù)讀取更高效

????? 在硬件設(shè)計(jì)中,數(shù)據(jù)讀取的處理器只能從地址為k的倍數(shù)內(nèi)存處開始讀取數(shù)據(jù)呈驶,這種讀取方式相當(dāng)于將內(nèi)存分為多個(gè)塊拷泽,如果內(nèi)存可以從任意位置開始存放的話,數(shù)據(jù)很可能會(huì)被分散到多個(gè)塊中袖瞻,處理分散在多個(gè)塊中的數(shù)據(jù)需要移除首位不需要的字節(jié)跌穗,然后進(jìn)行合并,非常耗時(shí)虏辫。為了提高數(shù)據(jù)的讀取效率蚌吸,程序分配的內(nèi)存不是連續(xù)存儲(chǔ)的,而是按首地址為k的倍數(shù)方式存儲(chǔ)砌庄,這樣就可以一次性讀取數(shù)據(jù)羹唠,而不需要額外的操作奕枢。

?? 2).在某些平臺(tái)上,不進(jìn)行內(nèi)存對(duì)齊會(huì)崩潰?

????? 不是所有的硬件平臺(tái)CPU都能訪問任意地址上的數(shù)據(jù)佩微,某些硬件平臺(tái)只能在某些地址處取得特定類型數(shù)據(jù)缝彬,否則會(huì)拋出硬件異常。

內(nèi)存對(duì)齊規(guī)則

?????? 定義有效對(duì)齊值為結(jié)構(gòu)體中最寬成員和編譯器/用戶指定對(duì)齊值中較小的那個(gè)哺眯。

1).結(jié)構(gòu)體起始地址為有效對(duì)齊值的整數(shù)倍

2).結(jié)構(gòu)體總大小為有效對(duì)齊值得整數(shù)倍

3).結(jié)構(gòu)體第一個(gè)成員偏移值為0谷浅,之后成員的偏移值為min(有效對(duì)齊值,自身大心套俊)的整數(shù)倍一疯。

相當(dāng)于每個(gè)成員要進(jìn)行對(duì)齊,并且每個(gè)結(jié)構(gòu)體也要進(jìn)行對(duì)齊夺姑。

內(nèi)存碎片

?????? 程序的內(nèi)存往往不是緊湊連續(xù)排布的墩邀,而是存在著許多碎片。我們跟據(jù)碎片的原因把碎片分為內(nèi)部碎片和外部碎片兩張類型:

1).內(nèi)部碎片:系統(tǒng)分配的內(nèi)存大于實(shí)際所需的內(nèi)存(內(nèi)存對(duì)齊機(jī)制)

2).外部碎片:不斷分配回收不同大小的內(nèi)存盏浙,由于內(nèi)存分布散亂眉睹,較大內(nèi)存無法分配。

繼承類布局

????? 繼承

????? 如果一個(gè)類繼承自另一個(gè)類废膘,那么它自身數(shù)據(jù)位于父類之后竹海。

????? 含虛函數(shù)的類

????? 如果當(dāng)前類包含虛函數(shù),則會(huì)在類的最前端占用4個(gè)字節(jié)丐黄,用于存儲(chǔ)虛表指針站削,它指向一個(gè)虛函數(shù)表, 虛函數(shù)表中包含當(dāng)前類的所有虛函數(shù)指針孵稽。

?? ?? 虛函數(shù)表?? 下一章詳細(xì)講解许起。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市菩鲜,隨后出現(xiàn)的幾起案子园细,更是在濱河造成了極大的恐慌,老刑警劉巖接校,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猛频,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蛛勉,警方通過查閱死者的電腦和手機(jī)鹿寻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诽凌,“玉大人毡熏,你說我怎么就攤上這事÷滤校” “怎么了痢法?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵狱窘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我财搁,道長(zhǎng)蘸炸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任尖奔,我火速辦了婚禮搭儒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘提茁。我一直安慰自己淹禾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布甘凭。 她就那樣靜靜地躺著稀拐,像睡著了一般火邓。 火紅的嫁衣襯著肌膚如雪丹弱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天铲咨,我揣著相機(jī)與錄音躲胳,去河邊找鬼。 笑死纤勒,一個(gè)胖子當(dāng)著我的面吹牛坯苹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播摇天,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼粹湃,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了泉坐?” 一聲冷哼從身側(cè)響起为鳄,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腕让,沒想到半個(gè)月后孤钦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纯丸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年偏形,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片觉鼻。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡俊扭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坠陈,到底是詐尸還是另有隱情统扳,我是刑警寧澤喘帚,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站咒钟,受9級(jí)特大地震影響吹由,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜朱嘴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一倾鲫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧萍嬉,春花似錦乌昔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至行冰,卻和暖如春溺蕉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背悼做。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工疯特, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肛走。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓漓雅,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親朽色。 傳聞我的和親對(duì)象是個(gè)殘疾皇子邻吞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

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

  • 內(nèi)存管理是C++最令人頭痛的問題,也是C++最有爭(zhēng)議的地方葫男。C++高手從中獲得了更好的性能抱冷,更大的自由,C++菜鳥...
    Codeapes閱讀 411評(píng)論 0 2
  • C++內(nèi)存分區(qū) C++存在如下的內(nèi)存分區(qū) 1)棧區(qū)(stack):由編譯器自動(dòng)分配釋放 腾誉,存放函數(shù)的 參數(shù)值徘层,局部...
    VictorHong閱讀 571評(píng)論 1 0
  • 內(nèi)存分配方式 在C++中,內(nèi)存分成5個(gè)區(qū)利职,他們分別是堆趣效、棧、自由存儲(chǔ)區(qū)猪贪、全局/靜態(tài)存儲(chǔ)區(qū)和常量存儲(chǔ)區(qū)跷敬。 在棧上創(chuàng)建...
    showaichuan閱讀 326評(píng)論 0 2
  • 簡(jiǎn)介 在C++中,內(nèi)存分成5個(gè)區(qū)热押,他們分別是堆西傀、棧斤寇、自由存儲(chǔ)區(qū)、全局/靜態(tài)存儲(chǔ)區(qū)和常量存儲(chǔ)區(qū)拥褂。棧:在執(zhí)行函數(shù)時(shí)娘锁,函...
    analanxingde閱讀 265評(píng)論 0 1
  • 1、內(nèi)存分配方式 在C++中饺鹃,內(nèi)存分為5個(gè)區(qū)莫秆,分別是堆、棧悔详、自由存儲(chǔ)區(qū)镊屎、全局/靜態(tài)存儲(chǔ)區(qū)和常量存儲(chǔ)區(qū)。 堆:new...
    星期八我一定好好讀書閱讀 155評(píng)論 0 0