分配连续的内存到一个二维数组声明后

问题描述:

据我所知,现代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个指数?

+0

这是在相同的[主题]过去帖(https://*.com/questions/1970698/使用-malloc的换分配-的-多维阵列与 - 不同排-lengt) –

同时确保指针及其指定区域。

这样

#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); 
} 

Demo.