天天看點

c語言自由存儲區,C/C++ 記憶體分區以及自由存儲區和堆的差別

作者: 駭客HK

出處:https://www.cnblogs.com/ruanraun/p/Heap.html

C/C++編譯的程式占用的記憶體分區

1、棧區(stack)— 由編譯器自動配置設定釋放 ,存放函數的參數名,局部變量的名等。其操作方式類似于資料結構中的棧。

2、堆區(heap)— 由程式員配置設定釋放, 若程式員不釋放,程式結束時可能由OS回收。注意它與資料結構中的堆是兩回事,配置設定方式倒是類似于連結清單。

3、全局/靜态存儲區 —全局變量和局部靜态變量的存儲是放在一塊的(在以前的C語言中,全局變量又分為初始化的和未初始化的,在C++裡面沒有這個區分)。程式結束後由系統釋放。

4、常量存儲區 — 常量字元串就是放在這裡的,正常情況不允許修改,程式結束後由系統釋放 。

5、程式代碼區 — 存放函數體的二進制代碼。

自由存儲區(free store) 和 堆區 (heap) ?

我參考了網上很多資料和文章關于C/C++的記憶體分區都把自由存儲區和堆區單獨區分了開來,很多C/C++記憶體分區分類都是如下分類:

1、棧區 —  (同上)

2、堆區 —  由malloc等配置設定的記憶體塊,它是用free來結束自己的生命的。

3、自由存儲區 — 由new配置設定的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般一個new就要對應一個delete。

4、全局/靜态存儲區 —  (同上)

5、常量存儲區 —   (同上)

我對第二種分類方式産生了如下疑問:自由存儲區與堆區的記憶體區域有可能相同嗎?

很多文章一般用來劃分自由存儲區與堆的分界線就是new/delete與malloc/free。而C語言很明确地知道malloc/free是在堆上進行記憶體操作。那麼new/delete申請銷毀的區域是否也在堆上呢?

我随後通過查閱相關的資料和文章,最終還是找到了答案:

裡面寫到

Free Store

The free store is one of the two dynamic memory areas, allocated/freed by new/delete. Object lifetime can be less than the time the storage is allocated; that is, free store objects can have memory allocated without being immediately initialized, and can be destroyed without the memory being immediately deallocated. During the period when the storage is allocated but outside the object's lifetime, the storage may be accessed and manipulated through a void* but none of the proto-object's nonstatic members or member functions may be accessed, have their addresses taken, or be otherwise manipulated.

Heap

The heap is the other dynamic memory area, allocated/freed by malloc/free and their variants. Note that while the default global new and delete might be implemented in terms of malloc and free by a particular compiler, the heap is not the same as free store and memory allocated in one area cannot be safely deallocated in the other. Memory allocated from the heap can be used for objects of class type by placement-new construction and explicit destruction. If so used, the notes about free store object lifetime apply similarly here.

Free Store

自由存儲是兩個動态記憶體區域之一,由NeX/Delphi配置設定/釋放。對象生存期可以小于存儲配置設定的時間;也就是說,空閑存儲對象可以在不立即初始化的情況下配置設定記憶體,并且可以在沒有立即釋放記憶體的情況下被銷毀。在存儲被配置設定但在對象的生命周期之外的期間,可以通過void*通路和操作存儲,但是可以通路原始對象的非靜态成員或成員函數中的任何一個,不具有它們的位址,或者以其他方式操作。

Heap

堆是另一個動态記憶體區域,由MALOC/FILE和它們的變體配置設定/釋放。請注意,雖然預設全局全局和删除可以用Malc和特定編譯器自由實作,但堆與自由存儲區不相同,并且在一個區域中配置設定的記憶體不能在另一個區域安全地釋放。從堆中配置設定的記憶體可以通過放置新構造和顯式銷毀來使用類類型的對象。如果使用的話,關于自由存儲對象壽命的注釋在這裡同樣适用。

是以關于自由存儲區與堆區得到以下結論:

堆是作業系統維護的一塊記憶體,而自由存儲是C++中通過new與delete動态配置設定和釋放對象的抽象概念。堆與自由存儲區并不等價。

但至于前面說‘new/delete所申請銷毀的區域也在堆上’這句話也不能算錯。

總結:

關于C/C++的記憶體分區前面兩種分類方式都不能算錯,造成分類的差異隻是因為C語言和C++語言發展和語言背景的差異罷了,而現在大多數人都喜歡用‘C/C++’來統稱這兩門語言,而所謂的‘C/C++’其實更多指的是C++(C++在語言的設計上,将C作為子集,基本保留了C語言的文法和特性)是以才産生了種種分内的差異。

參考文章

https://www.cnblogs.com/QG-whz/p/5060894.html

http://www.gotw.ca/gotw/009.htm

c語言自由存儲區,C/C++ 記憶體分區以及自由存儲區和堆的差別