變長數組(VLA)和調用malloc()在功能上有些重合。例如,兩者都可用于創建在運行時確定大小的數組:
int vlamal()
{
int n;
int * pi;
scanf("%d", &n);
pi = (int *) malloc (n * sizeof(int));
int ar[n]; // vla
pi[2] = ar[2] = -5;
...
}
不同的是,變長數組是自動存儲類型。因此,程序在離開變長數組定義所在的塊時(該例中,即vlamal()函數結束時),變長數組占用的內存空間會被自動釋放,不必使用free()。另一方面,用malloc()創建的數組不必局限在一個函數內訪問。例如,可以這樣做:被調函數創建一個數組并返回指針,供主調函數訪問,然后主調函數在末尾調用free()釋放之前被調函數分配的內存。另外,free()所用的指針變量可以與malloc()的指針變量不同,但是兩個指針必須存儲相同的地址。但是,不能釋放同一塊內存兩次。
對多維數組而言,使用變長數組更方便。當然,也可以用malloc()創建二維數組,但是語法比較繁瑣。如果編譯器不支持變長數組特性,就只能固定二維數組的維度,如下所示:
int n = 5;
int m = 6;
int ar2[n][m]; // n x m VLA
int (* p2)[6]; // works pre-C99
int (* p3)[m]; // requires VLA support
p2 = (int (*)[6]) malloc(n * 6 * sizeof(int)); // n * 6 array
p3 = (int (*)[m]) malloc(n * m * sizeof(int)); // n * m array
// above expression also requires VLA support
ar2[1][2] = p2[1][2] = 12;
先復習一下指針聲明。由于malloc()函數返回一個指針,所以p2必須是一個指向合適類型的指針。第1個指針聲明:
int (* p2)[6]; // works pre-C99
表明p2指向一個內含6個int類型值的數組。因此,p2[i]代表一個由6個整數構成的元素,p2[i][j]代表一個整數。
第2個指針聲明用一個變量指定p3所指向數組的大小。因此,p3代表一個指向變長數組的指針,這行代碼不能在C90標準中運行。