C与C++的内存机制的比较
C語言與C++內(nèi)存非常相似,這也是我一直搞不清楚他的原因;下面梳理一下他們之間的區(qū)別:
??1、先說C語言的內(nèi)存機(jī)制
棧????????位于函數(shù)內(nèi)的局部變量(包括函數(shù)實(shí)參),由編譯器負(fù)責(zé)分配和釋放,函數(shù)結(jié)束,棧變量失效;
堆????????由程序員用malloc()/calloc()/realloc()分配空間,free()釋放所申請(qǐng)的空間。如果程序員忘記free(),則會(huì)造成內(nèi)存泄漏,程序結(jié)束時(shí)可能會(huì)由操作系統(tǒng)回收,也許就一直占用著直至關(guān)機(jī)。
全局區(qū)/靜態(tài)區(qū)????????全局變量和靜態(tài)變量存放區(qū),程序一經(jīng)編譯好,該區(qū)域便存在。并且在C語言中初始化的全局變量和靜態(tài)變量和未初始化的放在相鄰的兩個(gè)區(qū)域(在C++中,由于編譯器會(huì)給全局變量和靜態(tài)變量自動(dòng)初始化賦值,所以沒有區(qū)分了)。由于全局變量一直占據(jù)內(nèi)存空間且不易維護(hù),推薦少用。程序結(jié)束時(shí)釋放。?
C風(fēng)格字符串常量存儲(chǔ)區(qū)????????專門存放字符串常量的地方,程序結(jié)束時(shí)釋放;
程序代碼區(qū)?????????存放程序二進(jìn)制代碼的區(qū)域。
? 2、再說C++的內(nèi)存機(jī)制
棧????????位于函數(shù)內(nèi)的局部變量(包括函數(shù)實(shí)參),由編譯器負(fù)責(zé)分配釋放,函數(shù)結(jié)束,棧變量失效。
堆????????這里與C不同的是,該堆是由new申請(qǐng)的內(nèi)存,由delete負(fù)責(zé)釋放。
自由存儲(chǔ)區(qū)? ? ? ??由程序員用malloc()/calloc()/realloc()分配空間,由free()釋放。如果程序員忘記free()了,則會(huì)造成內(nèi)存泄漏,程序結(jié)束時(shí)可能會(huì)有操作系統(tǒng)回收,也許就一直占用著直至關(guān)機(jī)。?與C的堆機(jī)制對(duì)應(yīng)。
全局區(qū)/靜態(tài)區(qū)????????全局變量和靜態(tài)變量存放區(qū),程序一經(jīng)編譯好,該區(qū)域便存在。在C++中,由于編譯器會(huì)給全局變量和靜態(tài)變量自動(dòng)初始化賦值,所以沒有區(qū)分初始化和未初始化變量。由于全局變量一直占據(jù)內(nèi)存空間且不易維護(hù),推薦少用。程序結(jié)束時(shí)釋放。
常量存儲(chǔ)區(qū)????????這是一塊比較特殊的存儲(chǔ)區(qū),專門存儲(chǔ)不能修改的常量(如果采用非正常手段更改,當(dāng)然也是可以的)。
下面舉個(gè)栗子,比較C與C++在全局區(qū)/靜態(tài)區(qū)的區(qū)別(Linux):
將文件編譯成可執(zhí)行文件,打印文件的大小:
可以看到,數(shù)據(jù)段(data,不包括bss)為252,bss(未初始化數(shù)據(jù)段)為16;
接下來將測(cè)試代碼進(jìn)行修改(對(duì)b進(jìn)行初始化):
#include?<stdio.h>static?int?a; int?b?=?1; int?c?=?1;int?main(void) {return?0; }將文件編譯成可執(zhí)行文件,打印文件的大小:
可以看到,數(shù)據(jù)段(data,不包括bss)為256(252+4),bss(未初始化數(shù)據(jù)段)為12(16-4);
與上面的那段代碼對(duì)比可以發(fā)現(xiàn),data增加了4,剛剛好是bss減少的4。現(xiàn)在,就可以確定C語言中,對(duì)全局區(qū)/靜態(tài)區(qū)中變量初始化與為初始化是放在不同區(qū)域的。
接下來看一下C++運(yùn)行的結(jié)果:
b未手動(dòng)初始化(int b;):
b手動(dòng)初始化為0(int b = 0):
上面在C++下面,數(shù)據(jù)段(data)沒有變化;因此在c語言中,全局變量又分為初始化的和未初始化的,在c++里面沒有這個(gè)區(qū)分了,他們共同占用同一塊內(nèi)存區(qū)。
但是,這里面有一個(gè)非常小的細(xì)節(jié)對(duì)于b的初始化,如果手動(dòng)初始化為0以外的數(shù)字,打印出來的data段又與C語言是一樣的:
b初始化為1:
b不初始化:
以上問題的出現(xiàn),是什么原因,還沒有查清楚。
可能的原因是:
BSS段(bss?segment)通常是指用來存放程序中未初始化的全局變量的一塊內(nèi)存區(qū)域。(0也算未初始化)
數(shù)據(jù)段(data?segment)通常是指用來存放程序中已初始化且不為0的全局變量的一塊內(nèi)存區(qū)域。(只有初始化為0之外的數(shù)字才算真正的初始化)
具體原因不知道,只是猜測(cè)。
轉(zhuǎn)載于:https://blog.51cto.com/10324228/2083826
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的C与C++的内存机制的比较的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 队列工厂之RabbitMQ
- 下一篇: 除了Open Day,Nibiru与Di