C語言記憶體

2021-09-25 18:36:53 字數 2312 閱讀 6220

全域性變數(外部變數):出現在**塊{}之外的變數就是全域性變數。

區域性變數(自動變數):一般情況下,**塊{}內部定義的變數就是自動變數,也可使用auto顯示定義。

靜態變數:是指記憶體位置在程式執行期間一直不改變的變數,用關鍵字static修飾。**塊內部的靜態變數只能被這個**塊內部訪問,**塊外部的靜態變數只能被定義這個變數的檔案訪問。

**區------程式被作業系統載入到記憶體的時候,所有的可執行**(程式**指令、常量字串等)都載入到**區,這塊內存在程式執行期間是不變的。**區是平行的。函式也是**的一部分,故函式都被放在**區,包括main函式。

靜態區------全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域, 未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。 - 程式結束後有系統釋放

棧區---------棧(stack)是一種先進後出的記憶體結構,由編譯器自動分配記憶體。存放函式的引數值,區域性變數的值等。棧區在程式執行期間是可以隨時修改的。當乙個自動變數超出其作用域時,自動從棧中彈出。

每個執行緒都有自己專屬的棧;

棧是從高位址向低位址方向增長,其最大尺寸固定,超出則引起棧溢位;

變數離開作用域後棧上的記憶體會自動釋放。

使用棧來實現的區域性變數定義時未初始化,則變數值是隨機數。

語句int a=15;c語言在編譯時會轉成

int a;

a=15;

不能將乙個棧變數的位址通過函式的返回值返回

堆區------堆(heap)和棧一樣,也是一種在程式執行過程中可以隨時修改的記憶體區域。一般比較複雜的資料型別都是放在堆中,一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由os** 。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶,

可以通過函式返回乙個堆位址,但記得一定用通過free函式釋放申請的堆記憶體空間,不釋放會出現記憶體洩漏

(1)申請方式

stack:

由系統自動分配。例如,宣告在函式中乙個區域性變數 int b; 系統自動在棧中為b開闢空間

heap:

需要程式設計師自己申請,並指明大小,在c中malloc,free函式

(2)申請後系統的響應

棧:只要棧的剩餘空間大於所申請空間,系統將為程式提供記憶體,否則將報異常提示棧溢位。

堆: 首先應該知道作業系統有乙個記錄空閒記憶體位址的鍊錶,當系統收到程式的申請時,會遍歷該鍊錶,尋找第乙個空間大於所申請空間的堆結點,然後將該結點從空閒 結點鍊錶中刪除,並將該結點的空間分配給程式,另外,對於大多數系統,會在這塊記憶體空間中的首位址處記錄本次分配的大小,這樣,**中的free語句才能正確的釋放本記憶體空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閒鍊錶中。

(3)申請大小的限制及生長方向

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

堆-------堆是向高位址擴充套件的資料結構,是不連續的記憶體區域。這是由於系統是用鍊錶來儲存的空閒記憶體位址的,自然是不連續的,而鍊錶的遍歷方向是由低位址向高位址。堆的大小受限於計算機系統中有效的虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大。

(4)申請效率的比較:

棧由系統自動分配,速度較快。但程式設計師是無法控制的。

堆是由malloc分配的記憶體,一般速度比較慢,而且容易產生記憶體碎片,不過用起來最方便.

char *p1 = (char *)malloc(10); 其中malloc申請的內存在堆區,但是變數p1在棧區,所以要呼叫堆區的內容,得先呼叫棧區內容。

另外,在windows下,最好的方式是用virtualalloc分配記憶體,他不是在堆,也不是在棧是直接在程序的位址空間中保留一快記憶體,雖然用起來最不方便。但是速度快,也最靈活。

(5)堆和棧中的儲存內容

棧------在函式呼叫時,第乙個進棧的是主函式中後的下一條指令(函式呼叫語句的下一條可執行語句)的位址,然後是函式的各個引數(在大多數的c編譯器中引數是由右往左入棧的),然後是函式中的區域性變數。注意靜態變數是不入棧的。當本次函式呼叫結束後,區域性變數先出棧,然後是引數,最後棧頂指標指向最開始存的位址,也就是主函式中的下一條指令,程式由該點繼續執行。

堆------一般是在堆的頭部用乙個位元組存放堆的大小。堆中的具體內容有程式設計師安排。

最後:作業系統在管理記憶體時,最小單位不是位元組,而是記憶體頁(32位作業系統的記憶體頁一般是4k)。比如,初次申請1k記憶體,作業系統會分配1個記憶體頁,也就是4k記憶體。因為:記憶體頁越大,記憶體浪費越多,但作業系統記憶體排程效率高,不用頻繁分配和釋放記憶體。

C語言記憶體

返回viod 型別的指標,同時為未初始化的記憶體空間。需要顯式的進行型別轉換,以及分配失敗處理,初始化 int p null 型別轉換 p int malloc sizeof int 分配失敗處理 if p null else 初始化處理 memset p,0,sizeof int 初始化處理 me...

C語言記憶體

1.ram和rom都是半導體儲存器,乙個叫隨機儲存器掉電丟失,乙個叫唯讀儲存器掉電儲存。2.ram又分為靜態和動態,靜態的速度非常快,動態的慢但是便宜,ddr ram是電腦中常用儲存器,動態記憶體中的動態是因為乙個dram單元儲存的是0還是1取決於電容是否有電荷,所以時間一長容易電荷變化,所以需要加...

C語言記憶體

1.一直對c語言記憶體的分布,不太清楚,模模糊糊,查了一些資料,簡單敘述下,以後工作中再結合工作看看 一 iar記憶體的分布,通過看生成的map檔案,分三個段 1 位址從低到高,先是 段 有對應的位址 主要是text ro code 跟ro data const唯讀資料 一般 段的資料都是儲存在記憶...