malloc、free、calloc 與realloc - OpenHome.cc

文章推薦指數: 80 %
投票人數:10人

在這段程式中, malloc 會配置一個 int 需要的空間,並傳回該空間的位址,可以使用指標 p 來儲存位址,就C11 規範來說, malloc 只配置空間但不初始空間的值,若要在 ... 回C語言目錄 到目前為止,變數建立後會配置記憶體空間,這類資源是配置在記憶體的堆疊區(Stack),生命週期侷限於函式執行期間,也就是函式執行過後,配置的空間就會自動清除。

若要將函式執行結果傳回,不能直接傳回這類被自動配置空間的位址,因為函式執行過後,該空間就會釋出,函式呼叫者後續若透過位址取用這些資源,會發生不可預期的結果,例如,不能直接將區域建立的變數位址或陣列位址傳回。

然而程式運行後,資源之間的互用關係錯綜複雜,有些資源「無法預期」被使用的生命週期,因為無法預期,也就有賴於開發者自行管理記憶體資源,也就是開發者得自行在需要的時候配置記憶體,這些記憶體會被配置在堆積區(Heap),不會自動清除,開發者得在不使用資源時自行釋放記憶體。

要自行配置記憶體,C可以使用malloc,它定義在stdlib.h,舉例來說,可以在程式中以動態方式配置一個int型態大小的記憶體,例如: int*p=malloc(sizeof(int)); 在這段程式中,malloc會配置一個int需要的空間,並傳回該空間的位址,可以使用指標p來儲存位址,就C11規範來說,malloc只配置空間但不初始空間的值,若要在配置完成後預設為型態的零值,可以使用calloc: int*p=calloc(1,sizeof(int)); 若要釋放記憶體,可以使用free函式,以下使用一個簡單的程式來示範動態配置的使用: #include #include intmain(intargc,char*argv[]){ int*p=malloc(100); printf("空間位址:%p\n",p); printf("儲存的值:%d\n",*p); *p=200; printf("空間位址:%p\n",p); printf("儲存的值:%d\n",*p); free(p); return0; } 執行結果: 空間位址:006F0D60 儲存的值:7274688 空間位址:006F0D60 儲存的值:200 動態配置的空間,在程式結束前不會自動歸還,必須使用free釋放空間,若大量動態配置而沒有適當使用free的話,由於空間一直沒有歸還,最後將導致整個記憶體空間用盡。

如果想配置連續個指定型態的空間,可以如下: int*p=malloc(sizeof(int)*1000); 這段程式碼動態配置了1000個int大小的空間,並傳回空間的第一個位址,配置後的空間資料是未知的,,可以使用calloc來宣告空間配置,每個int空間會被始為0,例如: int*p=calloc(1000,sizeof(int)); 配置的空間長度必須自行儲存下來,因為沒有任何方式,可以從p得知到底配置的長度是多少,配置得來的空間,在不使用時同樣是使用free釋放,方法如下: free(p); 下面這個程式是個動態配置空間,並模擬為陣列來操作的簡單示範: #include #include intmain(void){ intsize=0; printf("輸入長度:"); scanf("%d",&size); int*arr=malloc(size*sizeof(int)); printf("指定元素:\n"); for(inti=0;i #include intmain(void){ int**arr=calloc(2,sizeof(int*)); for(inti=0;i<2;i++){ arr[i]=calloc(3,sizeof(int)); } for(inti=0;i<2;i++){ for(intj=0;j<3;j++){ printf("%d",arr[i][j]); } putchar('\n'); } for(inti=0;i<2;i++){ free(arr[i]); } free(arr); return0; } 記得最後要釋放配置的空間時,也要如以上範例逐一釋放,執行結果如下: 000 000 既然可以動態配置,那每段模擬的一維陣列長度當然可以不一樣囉! #include #include intmain(void){ int**arr=calloc(2,sizeof(int*)); arr[0]=calloc(3,sizeof(int)); arr[1]=calloc(5,sizeof(int)); for(intj=0;j<3;j++){ printf("%d",arr[0][j]); } putchar('\n'); for(intj=0;j<5;j++){ printf("%d",arr[1][j]); } putchar('\n'); for(inti=0;i<2;i++){ free(arr[i]); } free(arr); return0; } 執行結果: 000 00000 如果要改變已配置的記憶體大小,可以使用realloc,例如: #include #include intmain(void){ intsize=0; printf("陣列長度:"); scanf("%d",&size); int*arr1=calloc(size,sizeof(int)); printf("指定元素:\n"); for(inti=0;i



請為這篇文章評分?