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