c primer plus P340
爲了在程序運行時分配內存。 在頭文件stdlib.c中有malloc()和free()的原型。
malloc()接受一個參數:所需內存字節數,然後malloc()找到可用內存中一個大小適合的塊,返回那塊內存第一個字節的地址。
ANSI C標準使用了一個新類型:指向void的指針,被用作“通用指針”。
例:
double *ptd;
ptd = (double *)malloc(30 * sizeof(double)); //以前沒理解malloc和void的意思的時候,感覺這句話怎麼這麼麻煩,但是理解了之後才發現,這句話真的是詞詞不可少啊。
因爲數組的名字是它第一個元素的地址,反過來用,可以用ptd當作數組名,使用ptd[0]訪問內存塊的第一個元素,ptd[1]訪問第二個元素。
如前,C99引入了動態數組。
然而,即使在C99之前的編譯器中,也可以這樣做:
ptd = (double *)malloc(n * sizeof(double));
對應每個malloc()調用,應該調用一次free(). 函數free()的參數是先前malloc()返回的地址,它釋放先前分配的內存。
exit()的原型也在stdlib.c中。 exit()用來在內存分配失敗時結束程序。值EXIT_FAILURE 也在這個頭文件中定義。標準庫提供了兩個保證能夠在所有操作系統下工作的返回值:EXIT_SUCCESS (或者,等同於0)指示程序正常終止,EXIT_FAILURE指示程序異常終止。
例12.14:
while(i < max && scanf("%lf", &ptd[i]) == 1) //這裏允許輸入至多max個數據,i記錄輸入了多少
++i;
printf("Here are your %d entries: /n", number = i
); //這裏輸出i值的同時,將number賦值
for(i = 0; i < number; i++) //i回成0,number作爲那個"哨兵",將輸入的輸出依次讀出來
。。。
另外注意:putchar()裏面的參數需要是個字符,不能是字符串,所以要用單引號不要用雙引號。要是想換行的話:putchar('/n');
接上面的for語句:
{
printf("%7.2f", ptd[i]);
if(i % 7 == 6) //滿六個數換行
{
putchar('/n');
}
}
if(i % 7 != 0) //最後一行,不滿六個,換行
{
putchar('/n');
}
puts("Done");
注意free()函數,在這個特定的例子中,使用free()不是必須的,因爲在程序終止後所有已分配的內存都將被自動釋放。然而在一個更復雜的程序中,能夠釋放並在利用內存將是重要的。
內存泄漏 memory leak
函數calloc():
long * newmem;
newmem = (long*)calloc(100, sizeof(long));
calloc()函數有兩個參數,第一個是所需內存單元的數量,第二個是每個單元以字節計的大小。
函數calloc()還有一個特性,它將塊中的全部位都置爲0.
函數free()也可以用來釋放由calloc()分配的內存。
動態內存分配和變長數組:
變長數組VLA,是自動存儲的,在運行完定義部分之後會自動釋放。
二維數組:
int n = 5;
int m= 6;
int ar2[n][m];
int (*p2)[6]; //p2指向一個包含6個int值的數組。p2[i]將被解釋爲一個由6個整數構成的元素,p2[i][j]將是一個int值。
int (*p3)[m];
p2 = (int (*)[6]) malloc(n * 6 * sizeof(int)); //n*6數組
p3 = (int (*)[m]) malloc(n * m *sizeof(int)); //n*m數組