[英]Correct way to allocate and free arrays of pointers to arrays
我想創建一個指向3個浮點數組的指針數組。 這樣做的正確方法是什么?
float *array1[SIZE]; // I think it is automatically allocated
// OR
float **array1 = calloc(SIZE, sizeof(float*));
free(array1);
for (int i = 0; i < SIZE; i++) {
array1[i] = (float[]){0,0,0};
// OR
array1[i] = calloc(3, sizeof(float));
}
那么我將如何釋放數據呢? 我很確定只有free(array1);
不會工作,所以我會釋放數組中的每個指針然后釋放數組,或者因為我分配了三個浮點數,我會釋放每個浮點數,然后每個3浮點數組,然后整個數組???
如果你在編譯時知道數組大小(如果你知道,如果SIZE
是編譯時常量),你應該只聲明一個二維數組。 你根本不需要釋放它(也絕不能)。
float array1[SIZE][3];
只有在編譯時不知道維度時,才需要使用calloc
並創建指針數組。 在這種情況下,每次調用calloc
都應該有一個free
的調用。 並且由於在釋放數組后無法使用數組,因此在釋放array1
之前需要釋放行數組。
float **array1 = calloc(nrows, sizeof (float *));
for (int i=0; i < nrows; i++)
array1[i] = calloc(3, sizeof(float));
// Use it...
// Now free it
for (int i=0; i < nrows; i++)
free(array1[i]);
free(array1);
編輯:如果您不重新排列指針(例如,對行進行排序),您只需使用一個calloc
(以及之后的一次free
調用)即可完成所有這些操作:
float (*array1)[3] = calloc(3*nrows, sizeof (float));
這是因為列數在編譯時是已知的,這就是所有指針算術需要知道的。 然后你可以編寫像array1[i][j]
這樣的東西,你仍然可以傳遞array1[i]
,好像它是一個指向行的真實指針。 C很棒,利用它!
我想創建一個指向3個浮點數組的指針數組。 這樣做的正確方法是什么?
為什么要一個array of pointers to arrays
? array of arrays
不足夠嗎? (請記住,數組已經是指針式的,它們不是通過值傳遞的,而是當數組作為參數傳遞給函數時傳遞第一個元素的地址)。
// stack allocation, no need to free
float array[SIZE][3];
for (int i = 0; i < SIZE; i++) {
// do something with array[i][0], array[i][1], array[i][2]
}
那么我將如何釋放數據呢?
在這種情況下,您不會,因為數據是堆棧分配的(一旦超出范圍將自動清理)。 請記住,經驗法則是,對於您所做的每個內存分配,都需要相應的空閑。 因此,如果為浮點數組分配內存,就像在
float* arr = malloc(sizeof(float) * 3); // array of 3 floats
然后你只需要在malloc'd
的數組上調用malloc'd
,而不需要釋放單獨的浮點數。 如果您執行嵌套分配,請執行
// array of length SIZE, consisting of float pointers
float** arr = malloc(sizeof(float*) * SIZE);
// allocate the array of 3 floats at each index
for (int i = 0; i < SIZE; i++)
arr[i] = malloc(sizeof(float) * 3);
然后你需要為每個malloc
執行一個free
的,就像在
// free the individual arrays
for (int i = 0; i < SIZE; i++)
free(arr[i]);
// free the array of arrays
free(arr);
這里要取消的教訓是避免將數組全部動態分配。 堅持使用std::vector
或堆棧分配的數組。
一般規則是, 每次調用malloc()
或calloc()
,都需要對返回的指針執行free()
調用 。
如果你想要一個編譯時已知大小的二維數組,只需使用二維數組! float val[5][3]
完全有效。
如果你想要一個二維數組並且在編譯期間你不知道它的大小,你很可能想要使用一個標准的,單個的dieca()和一個合適的getter。
#define ARR_COLUMNS 10
#define ARR_ROWS 10
float* arr = calloc (ARR_COLUMNS * ARR_ROWS, sizeof(float));
int get(float* arr, int x, int y) {
if (x<0 || x>= ARR_COLUMNS) return 0;
if (y<0 || y>= ARR_ROWS) return 0;
return arr[ARR_COLUMNS*y+x];
}
void set (int* arr, int x, int y, float val) {
if (x<0 || x>= ARR_COLUMNS) return;
if (y<0 || y>= ARR_ROWS) return;
arr[ARR_COLUMNS*y+x] = val;
}
當然用適當的變量替換定義。
通過這樣做,您將:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.