1. 程式人生 > >C語言中動態分配陣列指標的釋放問題

C語言中動態分配陣列指標的釋放問題

我們都知道要實現根據程式的需要動態分配儲存空間,在C中需要使用到stdlib.h中的兩個函式,malloc,free,兩個函式的介紹如下:

malloc函式的原型為:

void *malloc (u igned int size)
其作用是在記憶體的動態儲存區中分配一個長度為size的連續空間。其引數是一個無符號整形數,返回值是一個指向所分配的連續儲存域的起始地址的指標。還有一點必須注意的是,當函式未能成功分配儲存空間(如記憶體不足)就會返回一個NULL指標。所以在呼叫該函式時應該檢測返回值是否為NULL並執行相應的操作。
void free(void *p)
作用是釋放指標p所指向的記憶體區。

其引數p必須是先前呼叫malloc函式或calloc函式(另一個動態分配儲存區域的函式)時返回的指標。給free函式傳遞其它的值很可能造成宕機或其它災難性的後果。

對於一般變數的動態分配和釋放比較簡單,這裡不介紹,我主要想介紹一下動態分配陣列,在free的時候需要注意的事項。

要記住一句話,“在free時,重要的是指標的值,而不是用來申請動態記憶體的指標本身”。

比如下面的程式段:

int *p = NULL;//宣告一個指向Int型的指標,這裡用來接收malloc返回的地址空間的首地址

p = (int *)malloc(sizeof(int) * 10);//動態分配10個int型大小的地址段,並將首地址存入p

...下面的這些語句省略,這些語句將p指向了剛剛分配的地址段的中間,比如說指向了p+5;

free(p);//該語句有可能導致宕機或者嚴重的後果,為什麼呢?

這其實就是因為,剛剛我們強調的那句話,malloc和free是對應的,他們的這種對應體現在地址段上面,也就是地址的值上面,並不體現在指標變數上。從表面看,這段程式是正確的,其實不然。

那麼,如何改正呢?

有兩種方法:第一種方法:

在p = (int *)malloc(sizeof(int) * 10);//動態分配10個int型大小的地址段,並將首地址存入p

後面,用另外一個指標變數儲存p的值,然後在free的時候,將該指標變數作為引數傳入。

第二種方法:

在free(p);這個語句之前,先把p重新指向分配的空間的首地址。

其中第一種方法比較容易理解和使用。

道理其實就是系統給你分配2000到8000的地址段,那麼你也要還給系統2000到8000的地址段,而不能還給系統3000到9000的地址段,雖然長度一樣,不過系統可不接受。