C與C++記憶體機制的不同
C與C++的記憶體機制雖然非常相似,但還是有些不同的地方
一.C記憶體機制
1. 棧(Stack):
棧記憶體只在程式運行時出現,在函數內部使用的變數、函數的參數以及返回值將使用棧空間,棧空間由編譯器自動分配和釋放。
2. 堆(Heep):
由malloc()/calloc()/realloc分配空間,free()釋放所申請的空間。如果忘記free(),則會造成記憶體泄露,程式結束時可以會由系統回收,也許就一直佔有著直至關機。
3. 全域區/靜態區:
全域變數和靜態變數存放區,程式一經編譯,該區便存在。並且在C語言中初始化的全域變數和靜態變數和未初始化的存放在相鄰的兩個地區(在C++中,由於編譯器會給全域變數和靜態變數自動初始化賦值,所以沒有區分)。由於全域變數一直佔據記憶體空間且不易維護,推薦少用。程式結束時釋放。
未初始化資料區段(BSS)
未初始化資料是在程式中聲明,但是沒有初始化的變數,在這些變數在程式運行之前不需要佔用儲存空間的空間。
唯讀資料區段
唯讀資料區段是程式使用的一些不會被更改的資料,使用這些資料的方式類似查表式的操作,由於這些變數不需要更改,因此只需要放置在唯讀記憶體中即可。
已初始化讀寫資料區段(RW data)
已初始化資料是在程式中聲明,並且具有初值的變數,這些變數需要佔用儲存空間的空間,在程式執行時它們需要位於可讀寫的記憶體地區內,並具有初值,以供程式運行時讀寫。
4. 程式碼段
程式碼片段由程式中執行的機器程式碼群組成。在C語言中,程式語句進行編譯後,形成機器代碼。在執行程式的過程中,CPU的程式計數器指向程式碼片段的每一條機器代碼,並由處理器依次運行。
程式碼片段、唯讀資料區段、讀寫資料區段、未初始化資料區段屬於靜態地區,而堆和棧屬於動態地區。程式碼片段、唯讀資料區段和讀寫資料區段將在串連之後產生,未初始化資料區段將在程式初始化的時候開闢,而堆和棧將在程式的運行中分配和釋放。
C語言程式分為映像和運行時兩種狀態。在編譯-串連後形成的映像中,將只包含程式碼片段(Text)、唯讀資料區段(ROData)和讀寫資料區段(RWData)。在程式運行之前,將動態產生未初始化資料區段(BSS),在程式的運行時還將動態形成堆(Heap)地區和棧(Stack)地區。
二.C++記憶體機制
1. 棧(Stack)
位於函數內的局部變數(包括函數實參),由編譯器負責分配釋放,函數結束,棧變數失效
2. 堆(Heap)
這裡與C不同的是,該堆是由new申請的記憶體,由delete負責釋放。
3. 自由儲存區:
由malloc()/calloc()/realloc()分配空間,由free()釋放。如果忘記free()了,則會造成記憶體泄露,程式結束時可能會由作業系統回收,也許就一直到關機。
4. 全域區/靜態區
全域變數和靜態變數存放區,程式一經編譯,該區就存在。在C++中,由於編譯器會給全域變數和靜態變數自動初始化賦值,所以沒有區分初始化和未初始設定變數。
5. 常量儲存區:
這是一塊比較特殊的儲存區,專門儲存不能修改的常量(如果採用非正常手段更改,當然也是可以的)。