据我所知,现代C标准允许我为2d数组分配一块内存,如下所示:
size_t rows, cols;
// assign rows and cols
int (*arr)[cols] = malloc(sizeof(double[cols][rows]));
但有没有办法在声明后为二维数组分配一块内存?例如。我在其他地方声明了一个外部变量我想将内存分配给:
size_t rows, cols;
extern int **arr;
//Malloc block to 2d array
我知道,例如,可以使用单个索引代替2 [i] [j] - > [i * rows + j] 但我想知道我是否可以保留2个指数?
答案 0 :(得分:1)
同时保护指针及其指向区域。
像这样#include <stdio.h>
#include <stdlib.h>
int **arr;
int **Malloc_block_to_2d_array(size_t rows, size_t cols){
int **arr = malloc(rows * sizeof(*arr) + rows * cols * sizeof(**arr));
if(arr){
char *body_top = (char*)arr + rows * sizeof(*arr);
for(size_t r = 0; r < rows; ++r){
arr[r] = (int *)(body_top + r * cols * sizeof(**arr));
}
}
return arr;
}
int main(void){
//DEMO
size_t rows = 3;
size_t cols = 5;
arr = Malloc_block_to_2d_array(rows, cols);
for(size_t r = 0; r < rows; ++r)
for(size_t c = 0; c < cols; ++c)
arr[r][c] = (r+1)*10 + c+1;
for(size_t r = 0; r < rows; ++r){
for(size_t c = 0; c < cols; ++c)
printf("%d ", arr[r][c]);
puts("");
}
free(arr);
}
答案 1 :(得分:1)
你不能&#34;保留&#34;两个索引,因为extern int **arr
没有声明连续的2D数组。它是一个指针数组,因此编译器使用它的两个索引的机制与用于2D数组的机制非常不同。
最大的区别是访问2D数组需要编译器知道cols
的值,而访问指针数组则不然。
声明
int (*arr)[cols] = malloc(sizeof(double[cols][rows]));
是一个可变长度数组。在静态上下文中不允许这样做,因此arr
不能是全局的。
你可以将一个指针数组变成连续的块。双索引表达式将起作用,代价是分配一个额外的数组:
// In the header
extern size_t rows, cols;
extern double **arr;
// In the C file
size_t rows, cols;
double **arr;
void init_array(size_t r, size_t c) {
rows = r;
cols = c;
double (*a)[cols] = malloc(sizeof(double[cols][rows]));
arr = malloc(rows*sizeof(double*));
for (size_t i = 0 ; i != rows ; i++) {
arr[i] = a[i];
}
}
void free_array() {
free(arr[0]);
free(arr);
}