分配连续的内存到一个二维数组声明后
问题描述:
据我所知,现代C标准让我分配的内存块到一个二维数组如下:分配连续的内存到一个二维数组声明后
size_t rows, cols;
// assign rows and cols
int (*arr)[cols] = malloc(sizeof(double[cols][rows]));
但有分配的块的方式内存声明后的2d数组?例如。我有别处声明的外部变量我想分配内存以:
size_t rows, cols;
extern int **arr;
//Malloc block to 2d array
我知道这是可能的,例如,代替2 [i] [j]使用单个索引 - > [I * rows + j] 但我想知道我是否可以保留2个指数?
答
同时确保指针及其指定区域。
这样
#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);
}
答
你不能“保留”两个指标,因为extern int **arr
不声明一个连续的二维数组。它是一个指针数组,因此编译器使用两个索引的机制与用于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);
}
这是在相同的[主题]过去帖(https://*.com/questions/1970698/使用-malloc的换分配-的-多维阵列与 - 不同排-lengt) –