2017-09-05 54 views
1

據我所知,現代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://stackoverflow.com/questions/1970698/使用-malloc的換分配-的-多維陣列與 - 不同排-lengt) –

回答

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

你不能「保留」兩個指標,因爲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.