【问题标题】:How to dynamically allocate a 2D array in one function and print it in another in C?如何在一个函数中动态分配二维数组并在 C 中将其打印到另一个函数中?
【发布时间】:2017-10-08 17:49:37
【问题描述】:

我想在一个函数中动态分配一个二维数组并在另一个函数中打印,但是 createMapBoard() 函数的返回值需要是指向数组地址的指针。下面是我的代码。它编译并打印出来,但只能来自 creatMapBoard() 函数。它不会在数组中读取 printMapBoard(**char) 函数,我不知道为什么。

#include <stdio.h>

char **createMapBoard(void);
void printMapBoard(char **board);
char **destroyMapBoard(char **board);

int main(){
    char **board = createMapBoard();
    printMapBoard(board);
    destroyMapBoard(board);
    printMapBoard(board);

    return 0;
}

char **createMapBoard(void){
    char **ptr[8][8];
    int i,j;
    char F = 'F';
    char K = 'K';
    char C = 'C';
    char D = 'D';
    char B = 'B';
    int n = 8;
    int m = 8;

    for(j=0; j<8; j++){
        for(i=0;i<8;i++){
            ptr[j][i] = ' ';
        }
    }

    ptr[0][0] = F;
    ptr[0][1] = F;
    ptr[1][1] = F;
    ptr[2][1] = F;
    ptr[2][2] = F;
    ptr[3][2] = F;
    ptr[4][2] = K;
    ptr[5][0] = C;
    ptr[5][3] = B;
    ptr[6][1] = C;
    ptr[6][2] = C;
    ptr[6][4] = D;
    ptr[7][2] = C;
    ptr[7][5] = D;
    ptr[7][6] = D;

    printf("========\n");

    for(j=0;j<8;j++){
        for(i=0;i<8;i++){
            printf("%c",ptr[j][i]);
        }
        printf("\n");
    }

    printf("========\n");
    printf("\n");

    return **ptr;
}

void printMapBoard(char **board){
    int j, i;
    printf("========\n");
    for(j=0;j<8;j++){
        for(i=0;i<8;i++){
            printf("%c", board[j][i]);
        }
        printf("\n");
    }
    printf("========\n");
    printf("\n");
}

char **destroyMapBoard(char **board){
    free(**board);
    free(board);

    return 0;
}

【问题讨论】:

  • createMapBoard 中,您不会动态创建任何内容。您的变量ptr 是一个由 8 个数组组成的数组,其中包含 8 个指向 char 的指针。可能不是你想要的。
  • 好的,那如何在createMapBoard函数中动态分配内存呢?
  • 你试过搜索吗?仅在此站点上就有数千个示例,可能在整个 Internet 上都有数百万个示例。尝试在您喜欢的搜索引擎中输入c allocate 2d array dynamically example 并查看结果。
  • 指针指向二维数组的示例,如this

标签: c multidimensional-array printing project dynamic-allocation


【解决方案1】:

有一些方法可以在 C 中创建二维数组。我选择了指向指针的方法。

  1 #include <stdio.h>                                                                    
  2 #include <stdlib.h>                                                                   
  3                                                                                       
  4 const int row = 8;                                                                    
  5 const int col = 8;                                                                    
  6                                                                                       
  7 char **createMapBoard(void);                                                          
  8 void printMapBoard(char **board);                                                     
  9 int destroyMapBoard(char **board);                                                    
 10                                                                                       
 11 int main()                                                                            
 12 {                                                                                     
 13    char **board = createMapBoard();                                                   
 14                                                                                       
 15    printMapBoard(board);                                                              
 16    destroyMapBoard(board);                                                            
 17                                                                                       
 18    return 0;                                                                          
 19 }                                                                                     
 20                                                                                       
 21 char **createMapBoard(void)                                                           
 22 {                                                                                     
 23                                                                                       
 24    char **ptr;                                                                        
 25                                                                                       
 26    int i, j;                                                                          
 27                                                                                       
 28    char F = 'F';                                                                      
 29    char K = 'K';                                                                      
 30    char C = 'C';                                                                      
 31    char D = 'D';                                                                      
 32    char B = 'B';                                                                      
 33                                                                                       
 34    int n = 8; // rows                                                                 
 35    int m = 8; // columns                                                              
 36                                                                                       
 37    ptr = (char **)malloc( row * sizeof(char *) );                                     
 38    for (i = 0; i < row; ++i) {                                                        
 39       ptr[i] = (char *)malloc( col * sizeof(char *) );                                
 40    }                                                                                  
 41                                                                                       
 42    for (j = 0; j < row; j++){                                                         
 43       for (i = 0; i < col; i++) {                                                     
 44          ptr[j][i] = ' ';                                                             
 45       }                                                                               
 46    }                                                                                  
 47                                       
 48    ptr[0][0] = F;                                                                     
 49    ptr[0][1] = F;                                                                     
 50    ptr[1][1] = F;                                                                     
 51    ptr[2][1] = F;                                                                     
 52    ptr[2][2] = F;                                                                     
 53    ptr[3][2] = F;                                                                     
 54    ptr[4][2] = K;                                                                     
 55    ptr[5][0] = C;                                                                     
 56    ptr[5][3] = B;                                                                     
 57    ptr[6][1] = C;                                                                     
 58    ptr[6][2] = C;                                                                     
 59    ptr[6][4] = D;                                                                     
 60    ptr[7][2] = C;                                                                     
 61    ptr[7][5] = D;                                                                     
 62    ptr[7][6] = D;                                                                     
 63                                                                                       
 64    printf("========\n");                                                              
 65                                                                                       
 66    for (j = 0; j < row; j++) {                                                        
 67       for (i = 0; i < col; i++) {                                                     
 68         printf("%c",ptr[j][i]);                                                       
 69       }                                                                               
 70       printf("\n");                                                                   
 71    }                                                                                  
 72                                                                                       
 73    printf("========\n");                                                              
 74    printf("\n");                                                                      
 75                                                                                       
 76    return ptr;                                                                        
 77 }                                                                                     
 78                                                                                       
 79 void printMapBoard(char **board)                                                      
 80 {                                                                                     
 81    int j, i;                                                                          
 82    printf("========\n");                                                              
 83    for ( j = 0; j < row; j++) {                                                       
 84       for ( i = 0; i < col; i++) {                                                    
 85          printf("%c", board[j][i]);                                                   
 86       }                                                                               
 87       printf("\n");                                                                   
 88    }                                                                                  
 89    printf("========\n");                                                              
 90    printf("\n");                                                                      
 91 }                                                                                     
 92    
 93 int destroyMapBoard(char **board)                                                     
 94 {                                                                                     
 95    int i;                                                                             
 96    for (i = 0; i < col; ++i)                                                          
 97       free( board[i] );                                                               
 98                                                                                       
 99    free( board );                                                                     
100                                                                                       
101    return 0;                                                                          
102 }

【讨论】:

  • “有一些方法可以在 C 中创建 2D 数组”——但这个答案中没有 2D 数组......
【解决方案2】:
#include <stdio.h>
#include <stdlib.h>

char * createMapBoard(void);
void printMapBoard(char board[8][8]);
char **destroyMapBoard(char board[8][8]);

int main(){
    char (*board)[8] = (char (*)[8])createMapBoard();
    printMapBoard(board);
    destroyMapBoard(board);
    //printMapBoard(board);

    return 0;
}    

char *createMapBoard(void){
    char (*ptr)[8] = (char (*)[8])malloc(sizeof(char) * 8 * 8);
    int i,j;
    char F = 'F';
    char K = 'K';
    char C = 'C';
    char D = 'D';
    char B = 'B';
    int n = 8;
    int m = 8;

    for(j=0; j<8; j++){
        for(i=0;i<8;i++){
            ptr[j][i] = ' ';
        }
    }

    ptr[0][0] = F;
    ptr[0][1] = F;
    ptr[1][1] = F;
    ptr[2][1] = F;
    ptr[2][2] = F;
    ptr[3][2] = F;
    ptr[4][2] = K;
    ptr[5][0] = C;
    ptr[5][3] = B;
    ptr[6][1] = C;
    ptr[6][2] = C;
    ptr[6][4] = D;
    ptr[7][2] = C;
    ptr[7][5] = D;
    ptr[7][6] = D;

    printf("========\n");

    for(j=0;j<8;j++){
        for(i=0;i<8;i++){
            printf("%c",ptr[j][i]);
        }
        printf("\n");
    }

    printf("========\n");
    printf("\n");

    return (char *)ptr;
}    

void printMapBoard(char board[8][8]){
    int j, i;
    printf("========\n");
    for(j=0;j<8;j++){
        for(i=0;i<8;i++){
            printf("%c", board[j][i]);
        }
        printf("\n");
    }
    printf("========\n");
    printf("\n");
}

char **destroyMapBoard(char board[8][8]){
    free(board);

    return 0;
}

在解决如何分配 2D 数组并将其传递给另一个数组的原始问题之前,您的代码在几个方面被破坏了,这使得您很难谈论您的原始观点。在进入正题之前,让我们先修复它们。

首先,通过使用 ptr[j][i] = ' ' 之类的语句,您可能希望拥有一个 2D 字符数组,在这种情况下您应该这样声明 ptr。

char ptr[8][8]; // 2D array of chars

不是

char** ptr[8][8];  // 2D array of pointers to pointers to chars

其次,如果你想返回你在createMapBorad中创建的数组(ptr),那么你需要返回ptr,而不是**ptr。即,

return ptr;

不是

return ** ptr;

表达式 ** ptr 取消引用 ptr 两次,在这种情况下相当于 ptr[0][0],它将返回 'F' (0x46) 伪装成指向 chars 的指针(char ** )。然后您的 printMapBoard 访问地址 0x46,这会导致段错误。这几乎肯定不是你想要做的。

修复它们之后,如果您想返回“二维字符数组”而不是指针数组,则需要让 createMapBoard 返回 char* 而不是 char** 。 char** 是一个指针数组(指针)(指向字符)。

到目前为止,您至少需要将 createMapBoard 修复为:

char * createMapBoard(void) {
    char ptr[8][8];
    ...
    return (char *)ptr;
}

(我们还没有完成。敬请期待)。

顺便说一句,如果您可以说函数返回 2D 数组,而不是 char*(本质上是 1D 数组,因此您不能执行 a[i][j] 之类的操作),那就太好了,但 AFAIK C 可以不允许我们这样做。以下(假设的)代码是语法错误。

char[8][8] createMapBoard(void) {
    char ptr[8][8];
    ...
    return ptr;
}

所以你需要假装你返回一个常规的一维数组(char*)。您可以稍后将其转换为真正的 2D 数组(我们稍后会介绍)。

以这种方式修复 createMapBoard 后,您仍然会返回本地数组作为返回值的错误。这是错误的,因为本地数组的生命周期仅限于函数调用结束。所以代码

char * createMapBoard(void) {
    char ptr[8][8];
    ...
    return (char *)ptr;
}

语法上没问题,但打印出错误的结果。

你需要调用 malloc 来创建一个从函数返回后还活着的数组,比如:

char * createMapBoard(void) {
    char * ptr = (char *)malloc(sizeof(char) * 8 * 8);
    ...
    return ptr;
}

但是 ptr 本质上变成了 createMapBoard 函数中的一维数组,它可以进行类似的赋值

ptr[i][j] = ' '

不再有效。

使 ptr 成为二维数组的方法如下:

char (*ptr)[8] = (char (*)[8])malloc(sizeof(char) * 8 * 8);

受 C99 标准支持。

这样,编译器就知道ptr是一个指向每行元素个数为8的二维数组的指针(所以它可以正确计算出a[i][j]的地址)。

您可以让 printMapBorad 像这样简单地接受 char[8][8] 的参数:

void printMapBorad(char board[8][8]) {
   ...
}

总结:

  • 函数参数可以直接声明为二维数组(如 char a[8][8])
  • 局部变量可以通过char(* a)[8]声明为二维数组; (以及由 (char (* )[8])ordinary_ptr 类似投射的普通指针;
  • 函数返回类型不能声明为二维数组,AFAIK,因此您需要假装它们是一维数组(并根据需要将它们转换为适当的类型)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 2021-01-26
    • 2020-04-08
    • 2016-02-16
    • 2011-07-07
    相关资源
    最近更新 更多