1.儲存器
常用的儲存器型別如下:
2. 記憶體分配
參考鏈結
2.1 記憶體分配機制
(1)棧(stack):位於函式內的區域性變數(包括函式實參),由編譯器負責分配釋放,函式結束,棧變數失效。
(2)堆(heap):由程式設計師用malloc/calloc/realloc分配,free釋放。如果程式設計師忘記free了,則會造成記憶體洩露,程式結束時該片記憶體會由os**,但程式只要不結束,就有可能造成記憶體洩露。(程式設計師負責分配和釋放)
(3)全域性區/靜態區(global static area): 全域性變數和靜態變數存放區,程式一經編譯好,該區域便存在。並且在c語言中初始化的全域性變數和靜態變數和未初始化的放在相鄰的兩個區域(在c++中,由於全域性變數和靜態變數編譯器會給這些變數自動初始化賦值,所以沒有區分了)。由於全域性變數一直佔據記憶體空間且不易維護,推薦少用。程式結束時釋放。
(4)c風格字串常量儲存區: 專門存放字串常量的地方,程式結束時釋放。
(5)程式**區:存放程式二進位制**的區域。
2.2 堆和棧
堆(heap)
棧(stack)
2.3 堆疊區別
從以上介紹中,它們有如下區別:
棧是系統提供的功能,特點是快速高效,缺點是由限制,資料不靈活;而堆是函式庫提供的功能,特點是靈活方便,資料適應面廣,但是效率有一定降低。
棧是系統資料結構,對於程序/執行緒是唯一的;堆是函式庫內部資料結構,不一定唯一。不同堆分配的記憶體無法互相操作。
棧空間分靜態分配和動態分配,一般由編譯器完成靜態分配,自動釋放,棧的動態分配是不被鼓勵的;堆的分配總是動態的,雖然程式結束時所有的資料空間都會被釋放回系統,但是精確的申請記憶體/釋放記憶體匹配是良好程式的基本要素。
碎片問題:對於堆來講,頻繁的new/delete等操作勢必會造成記憶體空間的不連續,從而造成大量的碎片,使程式的效率降低;對於棧來講,則不會存在這個問題,因為棧是後進先出(lifo)的佇列。
生長方向:堆的生長方向是向上的,也就是向這記憶體位址增加的方向;對於棧來講,生長方向卻是向下的,是向著記憶體位址減少的方向增長。
分配方式:堆都是動態分配的,沒有靜態分配的堆;棧有兩種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如區域性變數的分配。動態分配則由alloca函式進行分配,但是棧的動態分配和堆不同,它的動態分配是由編譯器進行釋放,無需我們手工實現。
分配效率:棧是機器系統提供的資料結構,計算機在底層提供支援,分配有專門的堆疊段暫存器,入棧出棧有專門的機器指令,這些都決定了棧的高效率執行。而堆是由c/c++函式庫提供的,機制比較複雜,有不同的分配演算法,易產生記憶體碎片,需要對記憶體進行各種管理,效率比棧要低很多。
C語言學習 6 記憶體分配
一 傳統陣列的缺點 1 陣列的長度必須事先定製,且只能是常整數,不能是變數 intlen 5 inta len error 2 傳統形式定義的陣列,該程式的記憶體程式設計師無法手動釋放 include void f void 這二十個位元組的儲存空間程式設計師無法手動程式設計釋放它 只能在本函式執行...
C語言學習筆記 動態記憶體分配
記憶體分割槽 說明 程式 區 code area 存放函式體的二進位制 靜態資料區 data area 也稱全域性資料區,包含的資料型別比較多,如全域性變數 靜態變數 一般常量 字串常量。其中 注意 靜態資料區的內存在程式結束後由作業系統釋放。堆區 heap area 一般由程式設計師分配和釋放,若...
C語言學習筆記(五) 記憶體分配
void getmemory char p,int num void test1 輸出內容 xmgcc void test11 char getmemory2 void test2 函式返回位址都是不安全的,因為函式結束後,函式變數的記憶體都會變釋放,因此這個位址其他運用程式也可以用到,會被修改。解...