【C++】C++學(xué)習(xí)筆記之九:堆逛拱、棧與內(nèi)存管理

stack 棧

stack是存在于某作用域(scope)的一塊內(nèi)存空間(memory space)。例如當(dāng)調(diào)用函數(shù)時(shí)台猴,函數(shù)本身就會(huì)形成一個(gè)stack用來(lái)放置他所接受的參數(shù)朽合,以及返回地址。在函數(shù)體(function body)內(nèi)聲明的任何變量饱狂,其所使用的內(nèi)存塊都取自上述的stack旁舰。

heap 堆

heap又稱(chēng)System heap,是指由操作系統(tǒng)提供的一塊global內(nèi)存空間嗡官。程序可動(dòng)態(tài)分配(dynamic allocated)從中獲得若干區(qū)塊(block)

{
    Complex c1(1,2); //c1所占的空間在棧stack上
    Complex *p = new Complex(1,2);// Complex(1,2)是一個(gè)臨時(shí)變量箭窜,它所占的內(nèi)存空間是使用new關(guān)鍵字從heap堆中動(dòng)態(tài)分配得來(lái)的,
                                  // 并且這塊內(nèi)存由指針p指向
}

棧和堆上各種對(duì)象的生命周期

stack object 棧對(duì)象的聲明周期

上面例子中的C1就是stack object(存放在棧上的對(duì)象),其生命在作用與結(jié)束之際結(jié)束衍腥,這種作用域內(nèi)的對(duì)象又稱(chēng)auto objectlocal object磺樱,因?yàn)樗麜?huì)被“自動(dòng)清理”。

static object 靜態(tài)對(duì)象的生命周期

static object(靜態(tài)對(duì)象)其生命在作用域結(jié)束之后仍然存在婆咸,直到整個(gè)程序結(jié)束竹捉,其才會(huì)被“清理”。出了作用域的靜態(tài)對(duì)象尚骄,雖然存在但不可見(jiàn)块差。這種變量常可以用來(lái)作為計(jì)數(shù)器倔丈,用來(lái)記錄程序經(jīng)過(guò)作用域的次數(shù)憨闰。如下:

int count_function(){
    static cnt = 0;//static object在被定義的時(shí)候初始化,且只初始化這一次需五,再次進(jìn)入函數(shù)會(huì)略過(guò)此句鹉动。
    cnt++;
    return cnt;
}

global object 全局對(duì)象的生命周期

寫(xiě)在任何作用域之外(或稱(chēng)為在全局域中)的對(duì)象叫做global object(全局對(duì)象)。其生命在程序開(kāi)始時(shí)開(kāi)始宏邮,程序結(jié)束時(shí)結(jié)束泽示,可以把他看作是全局域中的靜態(tài)對(duì)象缸血。

heap object 堆對(duì)象的生命周期

{
    Complex *p = new Complex(1,2);
    ……
    delete p;
}

指針p所指向的對(duì)象就是heap object(堆對(duì)象),其生命始于new械筛,止于delete捎泻。在其作用域內(nèi)只new不delete,會(huì)發(fā)生內(nèi)存泄漏埋哟。如下:

{
   Complex *p = new Complex;
}

因?yàn)闂?duì)象指針p離開(kāi)作用域后就自動(dòng)釋放了笆豁。也就是指向堆內(nèi)被分配的這塊內(nèi)存的指針失效了,但是這塊堆上的內(nèi)存仍然被標(biāo)記為“已使用”定欧。而這塊內(nèi)存沒(méi)辦法通過(guò)delete p去釋放內(nèi)存渔呵,將永遠(yuǎn)被占用,直至程序結(jié)束砍鸠。如果這個(gè)作用域被程序多次經(jīng)過(guò)扩氢,每次都會(huì)分配內(nèi)存不釋放,就會(huì)耗光內(nèi)存爷辱,導(dǎo)致系統(tǒng)變慢录豺,甚至程序崩潰。

new和delete

newdelete分別是在系統(tǒng)堆中分配和釋放內(nèi)存的指令饭弓,必須成對(duì)使用双饥。除此之外還有new[] (array new)和delete[](array delete)分別是在系統(tǒng)堆中分配數(shù)組和釋放數(shù)組的,也要成對(duì)使用弟断。

new的編譯器原理

new一個(gè)不帶指針的heap object

Paste_Image.png

new一個(gè)帶指針的heap object

Paste_Image.png

delete的編譯器原理

delete一個(gè)不帶指針的heap object

Paste_Image.png

delete一個(gè)帶指針的heap object

Paste_Image.png

在VC編譯器上動(dòng)態(tài)分配內(nèi)存的原理

cookie和補(bǔ)位內(nèi)存塊

在VC編譯器中咏花,所有動(dòng)態(tài)分配的內(nèi)存塊的大小都是16byte的整數(shù)倍。并且都是以4byte的cookie頭和4byte的cookie尾作為動(dòng)態(tài)內(nèi)存的起始標(biāo)志阀趴。其中cookie頭尾的內(nèi)容一致庸推,保存了當(dāng)前動(dòng)態(tài)分配的內(nèi)存塊的大小使用與釋放與否的標(biāo)記信息转砖。
其中要求所有內(nèi)存塊都是16byte的整數(shù)倍是因?yàn)檗D(zhuǎn)換成十六進(jìn)制后最后一位都為0,如64byte:0x40搭盾,16byte = 0x10罪塔。剩下最后一位為0是為了標(biāo)記此塊內(nèi)存是正在使用(末位置1)還是已經(jīng)被釋放(末位置0)掌敬。
為了讓分配的內(nèi)存塊大小是16byte的整數(shù)倍孙援,可能會(huì)有多余的內(nèi)存需要填補(bǔ)乘碑,VC編譯器的做法是不足16整數(shù)倍字節(jié)的部分用00000000的內(nèi)存塊補(bǔ)足(4byte一條)。

debug模式

debug模式會(huì)額外再對(duì)象實(shí)際占用的內(nèi)存頭和尾分別加入32byte和4byte的debug信息塊据块,而release模式則沒(méi)有此信息码邻。

動(dòng)態(tài)分配內(nèi)存塊計(jì)算方式

debug模式下的動(dòng)態(tài)內(nèi)存分配的

內(nèi)存塊大小=cookie頭尾(4byte*2)+ debug頭尾(32byte+4byte)+數(shù)據(jù)實(shí)際占用空間 (n byte)+ 補(bǔ)位(pad byte)

release模式下的動(dòng)態(tài)內(nèi)存分配

release模式下只比debug少了debug信息的頭尾塊:
內(nèi)存塊大小=cookie頭尾(4byte*2)+數(shù)據(jù)實(shí)際占用空間 (n byte)+ 補(bǔ)位(pad byte)

類(lèi)對(duì)象數(shù)組的內(nèi)存占用情況

動(dòng)態(tài)分配類(lèi)對(duì)象數(shù)組的內(nèi)存占用除了上面介紹的cookie頭尾,debug頭尾瑰钮,補(bǔ)位內(nèi)存還會(huì)在實(shí)際占用內(nèi)存中多分配4byte用來(lái)存放數(shù)組的大忻疤病(size)
內(nèi)存塊大小=cookie頭尾(4byte2)+ debug信息頭尾 + size(4byte)+數(shù)據(jù)實(shí)際占用空間(n byte) 數(shù)組size +補(bǔ)位(pad byte)

Paste_Image.png

下面分別用圖來(lái)表示各種情況下內(nèi)存占用情況:

動(dòng)態(tài)分配不帶pointer的單個(gè)class對(duì)象(debug模式和release模式)

debug模式

Paste_Image.png

release模式

Paste_Image.png

動(dòng)態(tài)分配帶pointer的單個(gè)class對(duì)象(debug模式和release模式)

Paste_Image.png

動(dòng)態(tài)分配不帶pointer的class對(duì)象數(shù)組(debug模式和release模式)

Paste_Image.png

動(dòng)態(tài)分配帶pointer的class對(duì)象數(shù)組(debug模式和release模式)

Paste_Image.png

不成對(duì)使用new[]和delete[]的潛在危機(jī)

new[] 和delete[]必須成對(duì)使用,如果使用了new[]卻使用delete釋放浪谴,對(duì)于不帶指針的類(lèi)开睡,不會(huì)有任何影響,因?yàn)閿?shù)組元素對(duì)象苟耻,會(huì)自動(dòng)在作用域結(jié)束時(shí)釋放篇恒;但是,對(duì)于帶指針的類(lèi)凶杖,就會(huì)導(dǎo)致只調(diào)用一次析構(gòu)函數(shù)胁艰,即只有數(shù)組的第一個(gè)元素里分配的動(dòng)態(tài)內(nèi)存得到了釋放,其他元素的動(dòng)態(tài)內(nèi)存則發(fā)生內(nèi)存泄漏智蝠。而由cookie引領(lǐng)的那塊內(nèi)存會(huì)正常通過(guò)delete釋放腾么。也就是說(shuō),對(duì)于帶指針的類(lèi)對(duì)象數(shù)組杈湾,帶cookie的動(dòng)態(tài)內(nèi)存部分不會(huì)泄漏解虱,泄漏的是類(lèi)內(nèi)部通過(guò)指針指向的內(nèi)存部分

Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末漆撞,一起剝皮案震驚了整個(gè)濱河市殴泰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浮驳,老刑警劉巖悍汛,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異至会,居然都是意外死亡离咐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)奉件,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宵蛀,“玉大人,你說(shuō)我怎么就攤上這事瓶蚂√锹瘢” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵窃这,是天一觀(guān)的道長(zhǎng)瞳别。 經(jīng)常有香客問(wèn)我,道長(zhǎng)杭攻,這世上最難降的妖魔是什么祟敛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮兆解,結(jié)果婚禮上馆铁,老公的妹妹穿的比我還像新娘。我一直安慰自己锅睛,他們只是感情好埠巨,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布历谍。 她就那樣靜靜地躺著,像睡著了一般辣垒。 火紅的嫁衣襯著肌膚如雪望侈。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天勋桶,我揣著相機(jī)與錄音脱衙,去河邊找鬼。 笑死例驹,一個(gè)胖子當(dāng)著我的面吹牛捐韩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鹃锈,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼荤胁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了仪召?” 一聲冷哼從身側(cè)響起寨蹋,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扔茅,沒(méi)想到半個(gè)月后已旧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡召娜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年运褪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玖瘸。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秸讹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雅倒,到底是詐尸還是另有隱情璃诀,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布蔑匣,位于F島的核電站劣欢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏裁良。R本人自食惡果不足惜凿将,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望价脾。 院中可真熱鬧牧抵,春花似錦、人聲如沸侨把。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至弛作,卻和暖如春涕蜂,著一層夾襖步出監(jiān)牢的瞬間华匾,已是汗流浹背映琳。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蜘拉,地道東北人萨西。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像旭旭,于是被迫代替她去往敵國(guó)和親谎脯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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

  • 從三月份找實(shí)習(xí)到現(xiàn)在持寄,面了一些公司源梭,掛了不少,但最終還是拿到小米稍味、百度废麻、阿里、京東模庐、新浪烛愧、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,277評(píng)論 11 349
  • 之前寫(xiě)到了關(guān)于不帶有指針的class的設(shè)計(jì)思路和注意事項(xiàng)掂碱,但是對(duì)于C/C++語(yǔ)言來(lái)說(shuō)怜姿,還有一個(gè)非常重要的概念就是指...
    故事狗閱讀 592評(píng)論 0 1
  • Week2 Notes A.三大函數(shù):拷貝構(gòu)造,拷貝賦值疼燥,析構(gòu) string class這個(gè)不是標(biāo)準(zhǔn)庫(kù)里的stri...
    古來(lái)征戰(zhàn)幾人回閱讀 158評(píng)論 0 0
  • 文/魚(yú)三 蛛絲玉縷 經(jīng)過(guò)此番被暗算沧卢,悟空心里有了個(gè)疙瘩。 自己被壓在這大山里醉者,洞外就單單小玉兒一...
    魚(yú)三123閱讀 524評(píng)論 1 6
  • 使用: spring aop使用簡(jiǎn)單示例 開(kāi)啟單個(gè)bean的代理但狭,ProxyFactoryBean aop失效 a...
    WY_250e閱讀 212評(píng)論 0 0