周立功教授數年之心血之作《程序設計與數據結構》,電子版已無償性分享到電子工程師與高校群體,在公眾號回復【程序設計】即可在線閱讀。書本內容公開后,在電子行業掀起一片學習熱潮。經周立功教授授權,本公眾號特對本書內容進行連載,愿共勉之。
第一章為程序設計基礎,本文為1.9.1 malloc()函數和1.9.2 calloc()函數。
》》》》 1.9 動態分配內存
首先回顧一下內存分配,所有程序都必須預留足夠的內存存儲程序使用的數據,這些內存中有些是自動分配的。比如,聲明“int iNum;”為一個int類型的值預留了足夠的內存,或顯式指定分配一定數量的內存,“int pData[20];”聲明預留了20個內存位置,每個位置存儲的是int類型的值。聲明還為內存提供了標識符,因此可以使用iNum或pData識別數據。靜態數據在程序載入內存時分配的,自動數據是在程序執行時分配的,并在程序離開時銷毀。但C能做的遠不止這些,可以在程序運行時請求所需要的內存大小。
程序在運行時分配的內存空間稱之為“堆”的存儲池,雖然計算機在硬件上不直接支持堆,但C函數庫(stdlib.h)分別提供了用于動態內存分配和釋放的函數malloc()和free(),即在運行時根據需要創建一個存儲單元,在不需要時釋放。
》》》 1.9.1 malloc()函數
malloc()函數原型如下:
void *malloc(unsigned int size);
其中,void *表示該函數是指針函數,size為所需內存的字節數,可以用sizeof運算符計算每個元素所需要的空間數量和所有元素需要內存的字節數。如果分配成功,雖然malloc()不會為分配的內存賦名,但它確實返回了動態分配內存塊的首字節地址。因此可以將該地址賦給一個指針變量,并使用指針變量訪問這塊內存。如果分配不成功或內存不足,則返回空指針NULL。因此在使用它返回的指針之前,一定要先檢查返回值,否則可能會導致程序非正常終止。比如:
int *pi = malloc(sizeof(int));
if(pi != NULL){
// 指針沒有問題
}else{
// 無效的指針
}
malloc()函數可用于返回指向數組的指針、指向結構的指針等,所以通常該函數的返回值會被強制轉換為匹配的類型,但從C99版本開始,void *類型的指針不需要強制轉換地賦給所有的指針類型變量。
當編寫程序時,常常很難為數組估計合適的大小,較為方便的做法是等到程序運行時,再來確定數組的實際大小。其方法是用malloc()在程序執行期間為數組分配空間,然后通過指向數組第一個元素的指針訪問數組。假設正在編寫的程序需要n個整數構成的數組,這里的n可以在程序執行期間計算出來。首先需要聲明指針變量:
int * pi, n;
一旦n的值已知,就讓程序調用malloc()函數為數組分配存儲空間:
pi = malloc(n * sizeof(int));
if(pi == NULL) return -1;
當pi指向分配動態分配的內存塊時,就可以忽略pi是指針的事實,將它作為數組名使用,這是C語言數組和指針形成緊密關系的所帶來的便利。由于數組名是該數組首元素的地址,如果讓pi指向這個塊的首元素,便可以象使用數組名一樣使用它。即可以使用pi[0]訪問該塊的首元素,pi[1]訪問第2個元素,以此類推。比如,使用下列循環對pi指向的數組進行初始化:
for(i = 0; i 《 n; i++) pi[i] = 0;
動態內存分配可以提供更多的靈活性,比如:
char *pcStr;
char *pcStr = malloc(strlen(“OK!”) + 1);
strcpy(pcStr, “OK!”);
在這里,使用strlen()計算字符串的長度,一定要記得加上結束符NUL。為何不用sizeof呢?因為szieof會返回數組和指針的長度,而不是字符串的長度。
》》》 1.9.2 calloc()函數
雖然可以用malloc()函數為數組分配內存,但C語言提供了一種更好用的calloc()函數,其函數原型如下:
void *calloc(size_t nmenb, size_t size);
calloc()函數為nmemb個元素的數組分配內存空間,其中,每個元素的長度都是size個字節。如果要求的空間無效,那么此函數返回指針。在分配了內存之后,calloc()函數會通過將所有位設置為0的方式進行初始化。比如,調用calloc()函數為n個整數的數組分配存儲空間,且保證所有整數初始化為0。比如:
pi = calloc(n, sizeof(int));
因為calloc()函數會清楚分配的內存,而malloc()函數不會,所以可以調用以“1”作為第一個實參的calloc()函數,為任何類型的數據項分配空間。比如:
struct point{ int x, y;} *pi;
pi = calloc(1, sizeof(struct point));
在執行此語句后,pi將指向一個結構體,且此結構體的成員x和y都會被設為0。
-
周立功
+關注
關注
38文章
130瀏覽量
37749 -
大數據
+關注
關注
64文章
8908瀏覽量
137792 -
malloc
+關注
關注
0文章
53瀏覽量
82
原文標題:周立功:動態分布內存——malloc()函數與calloc()函數
文章出處:【微信號:ZLG_zhiyuan,微信公眾號:ZLG致遠電子】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論