周立功教授數年之心血之作《程序設計與數據結構》,書本內容公開后,在電子行業掀起一片學習熱潮。經周立功教授授權,本公眾號特對本書內容進行連載,愿共勉之。
第一章為程序設計基礎,本文為1.9.3 free()函數和1.9.4 realloc()函數。
>>>>1.9.3free()函數
對于程序而言,不可再訪問的內存塊被稱為垃圾,留有垃圾的程序存在內存泄漏現象。雖然一些語言提供了垃圾收集器用于垃圾的自動定位和回收,但C語言不提供。要求每個程序負責回收各自的垃圾,方法是調用free()函數釋放不需要的內存。
通常malloc()要與free()配套使用,當動態內存使用完畢時,如果不及時釋放的話,必然導致“內存泄露(即內存空間減少)”,進而影響程序的正常運行。釋放內存的free()函數原型如下:
void free(void *pointer);
即將malloc()返回的指針pointer作為參數傳給free()釋放內存。雖然free()函數允許收回不再需要的內存,但使用此函數會導致一個新的問題:懸空指針。雖然調用free(pi)函數會釋放pi,但不會改變pi本身。如果忘記了pi不再指向有效內存塊,那么混亂就有可能隨即而來:
char *pi = malloc(5);
free(pi);
strcpy(pi, "abc");// 錯誤
即修改了pi指向的內存是嚴重的錯誤,因為程序對此內存失去了控制權。事實上,懸空指針是很難發現的,因為幾個指針可能指向相同的內存塊,在釋放內存塊后,全部的指針都懸空了。有了free()函數,也可以用malloc()在運行時分配一塊連續的內存空間,達到改變數組大小的目的。比如:
char * pi = malloc(5);
即變量pi指向已經在堆內分配的5個連續字節,好像聲明了一個有5個字符的數組一樣,顯然動態數組就是分配在“堆”上,用指針變量引用的數組。分配動態數組的步驟如下:
● 聲明一個指針變量用于保存數組變量首元素的地址;
●調用malloc()為數組變量中的元素分配內存
●將malloc()的結果賦給指針變量。
由于不同的數據類型占用的內存大小不一樣,其大小為數組變量元素個數乘以每個元素所占內存的大小。比如,有5個int型元素的數組變量需要分配內存。比如:
int *pi = malloc(5 * sizeof(int));
和數組不同的是,當不再使用時,必須釋放內存。比如:
free(pi);
如果需要10個元素才夠用,那么應該先釋放原內存,然后再申請新內存。比如:
free(pi);
pi = malloc(10 * sizeof(int));
顯然,存放在原內存的數據不見了,為了保留原來的數據,需要再做些工作:
int *temp = pi; //讓temp指向原內存
pi = malloc(10 * sizeof(int)); //讓pi指向新內存
memcpy(pi, temp, 5 * sizeof(int));//將原內存的數據拷貝到新內存
free(temp); //釋放原內存
但上面的工作僅需一條語句即可完成,比如:
pi = realloc(pi, 10*sizeof(int));
由于free函數不會檢查傳入的指針是否為NULL,也不會在返回前將指針設置為NULL,因此程序員會創建自己的free函數,saferfree函數的接口和實現詳見程序清單 1.49和程序清單 1.50。
程序清單1.49saferfree()函數的接口(saferFree.h)
1 #pragma once
2 void saferFree(void **pp);
程序清單1.50saferfreeh函數接口的實現(saferFree.c)
1 #include
2 #include
3
4 void saferFree(void **pp)
5 {
6 if(pp != NULL && *pp != NULL)
7 free(*pp);
8 *pp = NULL;
9 }
10 }
如果使用saferFree宏調用saferFree函數,則可以省略類型轉換和傳遞指針的地址。即:
#define NewSaferFree(P) saferFree((void **)&p)
其調用形式如下:
int *pi = malloc(sizeof(int));
NewSaferFree(pi);
>>>1.9.4realloc()函數
alloc是allocate分配的縮寫,前綴re就是重新分配的意思。如果原內存后面還有剩余的話,realloc()只是修改分配表,還是返回原內存的地址;如果沒有剩余內存的話,realloc()將申請新的內存,然后將原內存的數據拷貝到新內存中,原內存將被free()釋放掉,realloc()返回新內存的地址。realloc()函數原型如下:
void *realloc(void *pointer, unsigned int size);
當調用realloc()函數時,point必須指向先前通過malloc、calloc或realloc的調用獲得的內存塊。size表示新分配內存的大小,以字節為單位。其作用是將pointer所指向的動態空間的大小改變為size,pointer的值不變。如果重新分配不成功,則返回NULL;如果通過malloc()已經獲得了動態空間,又不想改變其大小,則可以使用realloc()重新分配。
-
數據結構
+關注
關注
3文章
573瀏覽量
40135 -
周立功
+關注
關注
38文章
130瀏覽量
37642
原文標題:周立功:動態分布內存——free()函數與realloc()函數
文章出處:【微信號:ZLG_zhiyuan,微信公眾號:ZLG致遠電子】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論