C語言 關於系統記憶體分配機制的一些整理

2021-07-31 05:00:56 字數 2527 閱讀 5571

指向字串常量的指標和字串陣列在使用時是有區別的。

看下面兩個函式

//執行通過,返回「hello world」

char *ptrchar()

//執行錯誤,不能返回區域性變數

char *arrchar()

出現上面的原因在於指標pc指向的字串「hello world」存放在文字常量區,而陣列ac中存放的字串存放在棧區,當函式結束時,棧中的資料自動釋放。

再看下面:

char* r = "hello word!";

char b="hello word!";

//錯誤,r指向的是文字常量區,在編譯時就確定的,在程式結束時自動釋放。試圖修改文字常量會引起錯誤

*r = 'w';

//正確,修改陣列中的第乙個字元,b是在棧上分配的

*b = 'w';

乙個由c/c++編譯的程式占用的記憶體分為以下幾個部分:

1、棧區(stack)— 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。

2、堆區(heap) — 一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由os** 。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶。

3、全域性區(靜態區)(static)—,全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域, 未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。程式結束後由系統釋放。

4、文字常量區 —常量字串就是放在這裡的,程式結束後由系統釋放。

5、程式**區—存放函式體的二進位制**。

二、例子程式

int a = 0; //全域性初始化區

char *p1; //全域性未初始化區

main()

使用棧就象 :  我們去飯館裡吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。

使用堆就象 :  是自己動手做喜歡吃的菜餚,比較麻煩,但是比較符合自己的口味,而且自由度大。

棧和堆的區別

棧是由編譯器在需要時分配的,不需要時自動清除的變數儲存區。裡面的變數通常是區域性變數、函式引數等。堆是由malloc()函式(c++語言為new運算子)分配的記憶體塊,記憶體釋放由程式設計師手動控制,在c語言為free函式完成(c++中為delete)。棧和堆的主要區別有以下幾點:

(1)管理方式不同

棧編譯器自動管理,無需程式設計師手工控制;而堆空間的申請釋放工作由程式設計師控制,容易產生記憶體洩漏。

(2)空間大小不同

棧是向低位址擴充套件的資料結構,是一塊連續的記憶體區域。這句話的意思是棧頂的位址和棧的最大容量是系統預先規定好的,當申請的空間超過棧的剩餘空間時,將提示溢位。因此,使用者能從棧獲得的空間較小。

堆是向高位址擴充套件的資料結構,是不連續的記憶體區域。因為系統是用鍊錶來儲存空閒記憶體位址的,且鍊錶的遍歷方向是由低位址向高位址。由此可見,堆獲得的空間較靈活,也較大。棧中元素都是一一對應的,不會存在乙個記憶體塊從棧中間彈出的情況。

(3)是否產生碎片

對於堆來講,頻繁的malloc/free(new/delete)勢必會造成記憶體空間的不連續,從而造成大量的碎片,使程式效率降低(雖然程式在退出後作業系統會對記憶體進行**管理)。對於棧來講,則不會存在這個問題。

(4)增長方向不同

堆的增長方向是向上的,即向著記憶體位址增加的方向;棧的增長方向是向下的,即向著記憶體位址減小的方向。

(5)分配方式不同

堆都是程式中由malloc()函式動態申請分配並由free()函式釋放的;棧的分配和釋放是由編譯器完成的,棧的動態分配由alloca()函式完成,但是棧的動態分配和堆是不同的,他的動態分配是由編譯器進行申請和釋放的,無需手工實現。

(6)分配效率不同

棧是機器系統提供的資料結構,計算機會在底層對棧提供支援:分配專門的暫存器存放棧的位址,壓棧出棧都有專門的指令執行。堆則是c函式庫提供的,它的機制很複雜,例如為了分配一塊記憶體,庫函式會按照一定的演算法(具體的演算法可以參考資料結構/作業系統)在堆記憶體中搜尋可用的足夠大的空間,如果沒有足夠大的空間(可能是由於記憶體碎片太多),就有需要作業系統來重新整理記憶體空間,這樣就有機會分到足夠大小的記憶體,然後返回。顯然,堆的效率比棧要低得多。

堆和棧的區別主要分:

作業系統方面的堆和棧,如上面說的那些,不多說了。

還有就是資料結構方面的堆和棧,這些都是不同的概念。這裡的堆實際上指的就是(滿足堆性質的)優先佇列的一種資料結構,第1個元素有最高的優先權;棧實際上就是滿足先進後出的性質的數學或資料結構。雖然堆疊,堆疊的說法是連起來叫,但是他們還是有很大區別的,連著叫只是由於歷史的原因。

C 記憶體分配機制

首先,來談談c 的5個儲存區 1.棧 是分配給函式區域性變數的儲存單元,函式結束後,該變數的儲存單元自動釋放,效率高,分配的空間有限。2.堆 由new建立,由delete釋放的動態記憶體單元。如果使用者不釋放該記憶體,程式結束時,系統會自動 3.自由儲存區 由malloc建立,由free釋放的動態記...

C語言的記憶體的分配機制

指向字串常量的指標和字串陣列在使用時是有區別的。看下面兩個函式 執行通過,返回 hello world char ptrchar 執行錯誤,不能返回區域性變數 char arrchar 出現上面的原因在於指標pc指向的字串 hello world 存放在文字常量區,而陣列ac中存放的字串存放在棧區,...

C C 中的記憶體分配機制

本文是總和了其它的幾篇帖子,主要是 一 字串 乙個字元乙個位元組,加上最後的乙個結束符 0 其中,strlen函式返回的字串長度不包括 0 sizeof操作符返回的位元組長度是包括 0 的。二 結構體的儲存 typedef struct sample sizeof sample 為1個位元組 typ...