C語言 基礎入門 學習筆記(11) 堆管理

2021-09-29 14:19:26 字數 4290 閱讀 6328

記憶體區可以分為棧、堆、靜態儲存區和常量儲存區。

區域性變數、函式形參、臨時變數都是在棧上獲得記憶體的,它們的獲取方式都由編譯器自動執行。

從堆上獲取的空間都是程式設計師自行管理的。

使用堆管理要包含標頭檔案:stdlib.h

1.分配記憶體空間

malloc函式可以從堆上獲得指定位元組數的記憶體空間,宣告如下:

void

*malloc

(int n)

;

其中形參n為要求分配的位元組數,如果執行成功,malloc函式返回獲得的記憶體空間的首位址;如果失敗,返回null。

malloc函式分配的記憶體空間是未初始化的。因此,在使用該記憶體空間時,要呼叫memset函式來將其初始化為全0。函式宣告如下:

void

*memset

(void

*p,int c,

int n)

;

該函式可以將記憶體空間按位元組為單位置為指定的字元c。其中,p為要清零的記憶體空間的首位址,c為要設定的值,n為被操作的記憶體空間的位元組長度。

組合操作方式如下:

int

*p =

null

;p =

(int*)

malloc

(sizeof

(int))

;if(null

== p)

printf

("can't get memory!\n");

memset

(p,0

,sizeof

(int))

;

範例1

#include

#include

#include

intmain

(void

)printf

("%d\n"

,*p)

;//輸出分配的空間上的值

memset

(p,0

,sizeof

(int))

;//將p指向的空間清零

printf

("%d\n"

,*p)

;//輸入memset後的結果

*p =2;

//重新賦值

printf

("%d\n"

,*p)

;//再次檢視結果

此例子說明了一開始從堆上獲取到乙個位址,發現該位址之前的內容是乙個混亂的數,然後對該位址下的值進行清零,再進行賦值的過程。

2.釋放記憶體空間

從堆上獲取的記憶體空間在程式結束後,系統不會自動對其進行釋放,需要自行管理。乙個程式結束時,必須保證所有從堆上獲得的空間已被安全釋放,否則會造成記憶體洩漏

free函式可以實現釋放記憶體的功能。函式宣告如下:

void

free

(void

*p);

free函式釋放完指標指向的內容後,該指標會指向之前指向的地方,因此要對指標再置為null。

free

(p);

p =null

;

1.calloc函式

函式宣告如下:

void

*calloc

(int n,

int size)

;

如果執行成功,函式從堆上獲得size x n的位元組空間,並返回該空間的首位址。如果失敗,返回null。calloc函式得到的記憶體空間是經初始化的,內容全為0。calloc函式適合為陣列申請空間,可以將size設定為陣列元素的空間長度,將n設定為陣列容量。

範例2

#include

#include

#define size 5

intmain

(void

)//為p指向的size個int型空間賦值

for(i=

0;i)//輸出各個空間的值

for(i=

0;i)//釋放空間

2.realloc函式

該函式可以實現記憶體分配和記憶體釋放的功能。函式宣告如下:

void

*realloc

(void

*p,int n)

;

指標p必須為指向堆記憶體空間的指標。realloc函式將指標p指向的記憶體塊的大小改變為n位元組。realloc分配的空間未經初始化。

當p的值為null時,即realloc(null,n),其等效於malloc(n);=

當n的值為0時,即realloc(p,0),其等效於free( p );

範例3

#include

使用realloc函式時,它的指標必須是已指向某一塊堆上記憶體空間的。

c語言的內建陣列屬於靜態陣列,程式執行前就必須確定其陣列容量。

借助堆管理來實現動態陣列的基本思想就是陣列容量動態地按需分配。要求多少記憶體就分配多少記憶體,使用分配函式在堆上獲取指定大小的記憶體空間,最後將這塊記憶體空間的起始位址作為該陣列的首位址。

使用指標變數從堆上動態分配空間的方法可以模擬實現動態陣列。基本**如下:

元素型別名 *point =

null

;point =

(元素型別名 *

)malloc

(陣列容量 *

sizeof

(元素型別名));

或者元素型別名 *point =

null

;point =

(元素型別名 *

)calloc

(陣列容量 ,

sizeof

(元素型別名)

);

上述語句將指標point賦值為一塊堆上的記憶體空間的首位址;之後就可以像運算元組一樣來操作這塊記憶體空間。由於動態陣列是從堆上獲取的記憶體空間,因此在程式結束時,必須要手動釋放記憶體。

範例4

#include

#include

#include

//分配陣列

void

*alloc_array

(void

*p,const

int n,

const

int size)

memset

(p,0

,size*n)

;return p;

}//釋放陣列空間

練習1用malloc函式實現和calloc函式功能相同的函式

//calloc函式相比於malloc函式多了初始化的功能

#include

#include

#include

void

*my_calloc

(int n,

int size)

intmain

(void

)

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-r74lcpom-1573650958217)(https ?/img-blog.csdnimg.cn/20191113211529867.png)]

C語言基礎入門學習

c語言學習 c語言思想 程式 計算機可以識別和執行的指令。程式 資料結構 演算法 編碼 將已經設計好的演算法用計算機語言表示出來。結構化程式設計方法 自頂向下,逐步細化,模組化設計,結構化編碼。c語言基礎 符號常量 用大寫表示,不占用記憶體,故不能賦以新值。define pi 3.14 預編譯指令,...

C 語言入門學習筆記

c 語言入門學習筆記 一 c 是什麼 c 讀作 c sharp 是一種程式語言,它是為生成在 net framework 上執行的各種應用程式而設計的。c 簡單 功能強大 型別安全,而且是物件導向的。c 憑藉在許多方面的創新,在保持 c 語言風格的表現力和雅緻特徵的同時,實現了應用程式的快速開發。v...

C語言學習筆記11

define crt secure no warnings 1 include include void swap int pa,int pb 函式本身的形參可以接受外部變數的值,但會使用另外的位址儲存 intmain 傳值呼叫 函式的形參和實參分別占有不同的記憶體塊,對形參的修改不會影響實參 可以...