動態內存的使用
上一節的方法雖然可以避免溢出的問題,但會導致數據的丟失,下面我們就來學習一種更好的方法-動態內存的使用。由於動態內存是完全由用戶自行分配使用的,因此需要用到一些系統調用,下面我們就分別學習它們。
首先我們需要的是動態內存分配的系統調用calloc()函數,其函數原型為:
#include
void *malloc(size_t size);
void *calloc(size_t nmemb,size_t size);
函數malloc和calloc都用於分配動態內存空間,其中malloc中的參數size表示申請分配的內存空間的大小,以字節計;calloc的參數nmemb表示分配內存空間占的數據項數目,參數size表示每一個數據項的大小,以字節計。因此calloc函數分配大小為nmemb*size大小的內存空間。
calloc和malloc的最大區別在於calloc函數將初始化所分配的內存空間,把所有位置置為0。
調用成功時,它們的返回值都為被分配的內存空間的指針;調用失敗時,返回值為NULL。
當對一塊動態內存的使用結束後,需要手動將其釋放。其中用到的系統調用為free()函數,其函數原型為:
#include
void free(void *ptr);
參數ptr是指向要釋放的動態內存的指針,要注意在動態內存使用完畢後釋放它,以免造成內存洩漏。下面我們就具體編寫一個動態內存管理的例子。
程序4.2如下:
#include
#include
char *upcase(char *inputstring);
int main(void)
{
char *str1;
str1=upcase(“Everybody”); /*調用子函數upcase()*/
printf(“str1=%s\n”,str1);
free(str1);/*釋放內存*/
return 0;
}
char *upcase(char *inputstring)
{
char *newstring;
int counter,N;
N=strlen(inputstring); /*N為字符串長度*/
/*申請N+1個字節的內存空間,若出錯則報錯並退出*/
if(!(newstring=malloc(N+1)))
{
printf(“ERROR ALLOCATING MEMORY!\n”);
exit(255);
}
/*將原字符串拷貝到新申請的內存塊*/
strcpy(newstring,inputstring);
for(counter=0;counter
{
if(newstring[counter]>=97&&newstring[counter]<=122)
newstring[counter]-=32; /*將小寫字母轉換為大寫字母*/
}
return newstring;
}
結果分析:
在這個程序中,由於所使用的是動態內存,因此程序可以將子函數中分配的內存空間的指針返回到主函數中。同時,由於使用了動態內存,使得子函數可以靈活地分配所需要的內存空間(注:之所以要多申請一個字節的空間,是因為strlen在求字符串長度時,不包括結尾的“”標志,但拷貝字符串時需要為此字符串結束標志留出空間)。此程序的運行結果為:
EVERYBODY
注意:在此程序的子函數中之所以可以使用N=strlen(inputstring),是因為此時inputstring是一個確定的字符串。而上一節中的4.1程序,newstring是一個未初始化的字符數組,故不能用strlen來求其長度。