为连续声明的二维数组分配连续内存

时间:2017-09-05 01:32:41

标签: c arrays malloc

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

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

Demo.