heap & stack?
操作的內(nèi)存可以分為以下幾個(gè)部分:
*棧區(qū) stack: 由編譯器自動(dòng)分配和釋放,存放函數(shù)的參數(shù)值、局部變量等值,其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
*堆區(qū) heap: 一般由程序員分配和釋放满俗,若程序員不釋放,程序結(jié)束的時(shí)候可能由系統(tǒng)回收作岖。
*全局區(qū)(靜態(tài)區(qū))static : 全局變量和靜態(tài)變量存儲(chǔ)是放在一塊的唆垃,初始化的全局變量和靜態(tài)變量是在一塊區(qū)域,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域痘儡。程序結(jié)束后辕万,由系統(tǒng)釋放。
*文字常量區(qū):常量字符串就放在這里沉删,程序結(jié)束后由系統(tǒng)釋放渐尿。
*程序代碼區(qū):存放函數(shù)體的二進(jìn)制代碼。
這里是靜態(tài)變量和全局變量還有局部變量的存儲(chǔ)特點(diǎn)
可見全局變量和靜態(tài)變量在內(nèi)存中是連續(xù)分布的矾瑰,而本地變量和他們相差甚遠(yuǎn)啊砖茸。
申請(qǐng)方式
*棧:由系統(tǒng)自動(dòng)分配。例如在函數(shù)中聲明 int b, 系統(tǒng)自動(dòng)在棧中為b開辟空間殴穴。
*堆:由程序員自己分配空間凉夯,并且指明大小,在c中用malloc函數(shù)采幌,在c++中用new劲够。例如:char* p1 = (char*)malloc(10)和int *p2 = new int(10)。注意的是這里的p1和p2本身是在棧里的休傍。
申請(qǐng)后系統(tǒng)響應(yīng)
*棧:只要棧的剩余空間大于申請(qǐng)的空間征绎,就會(huì)為程序提供內(nèi)存,否則將報(bào)異常提示磨取,棧溢出人柿。
*堆:首先應(yīng)該知道操作系統(tǒng)有一個(gè)記錄空閑內(nèi)存地址的鏈表柴墩,當(dāng)系統(tǒng)受到程序的申請(qǐng)時(shí), 會(huì)遍歷該鏈表凫岖, 尋找第一個(gè)空間大于所申請(qǐng)空間的堆節(jié)點(diǎn)拐邪,然后將該節(jié)點(diǎn)從空閑節(jié)點(diǎn)鏈表中刪除, 并將該節(jié)點(diǎn)的空間分配給程序隘截。對(duì)于大多數(shù)系統(tǒng), 會(huì)在這塊內(nèi)存空間中的首地址處記錄本次分配的大小汹胃,這樣delete 語句才能正確的釋放本內(nèi)存空間婶芭。另外找到的堆節(jié)點(diǎn)的大小不一定正好等于申請(qǐng)的大小,系統(tǒng)會(huì)自動(dòng)的將多余的那部分重新放到空閑鏈表中着饥。
申請(qǐng)效率的比較
*棧:由系統(tǒng)自動(dòng)分配內(nèi)存犀农,速度較快。但是程序員無法控制宰掉。
*堆:由new分配的內(nèi)存呵哨,一般速度比較慢,而且容易產(chǎn)生內(nèi)存碎片轨奄,不過用起來最方便孟害。
看到一個(gè)很好的比喻: 使用棧就像是我們?nèi)ワ堭^吃飯,只管點(diǎn)菜付錢和吃挪拟, 吃飽了就走挨务,不必理會(huì)切菜、洗菜等準(zhǔn)備工作和洗碗玉组、刷鍋等掃尾工作谎柄。好處是快捷,但是自由度較小惯雳。 使用堆就好比是我們自己做菜朝巫,比較麻煩,但是符合自己的口味石景,而且自由度較大劈猿。