在 main 外部定义的函数内分配数组

Posted

技术标签:

【中文标题】在 main 外部定义的函数内分配数组【英文标题】:Allocate array in main inside a function which is defined outside of main 【发布时间】:2018-05-20 14:54:09 【问题描述】:

我正在尝试在函数内的数组上使用 calloc,但它不起作用。尝试调试时,我发现在函数内部,指针指向分配的内存,但在离开函数时,它又指向 NULL。尝试了各种变体,但似乎无法找到解决方案。

这是我的代码:

int main(int argc, char *argv[]) 
    int *rows = NULL, *solvedRows = NULL;
    int **board = NULL, **solvedBoard = NULL;
    allocateMemory(dim, &(*rows), &(*board));
    allocateMemory(dim, &(*solvedRows), &(*solvedBoard));


void allocateMemory(int dim, int** rows, int*** board) 
    rows = calloc(dim*dim,sizeof(int));
    board = calloc(dim, sizeof(int*));
    if (rows == NULL || board == NULL) 
        printf("Error: calloc has failed\n");
        exit(1);
    

需要帮助以了解问题所在以及如何解决问题。

编辑

我试过了:

*rows = calloc(dim*dim,sizeof(int));
*board = calloc(dim, sizeof(int*));

还是有同样的问题。

也试过了:

allocateMemory(dim, &rows, &board);

对于第 4 行和(第 5 行相同)和 in 编译时出现错误: “错误:从不兼容的指针类型 [-Werror=incompatible-pointer-types] 传递 'allocateMemory' 的参数 2 allocateMemory(dim, &rows, &board); ^" 错误:从不兼容的指针类型 [-Werror=incompatible-pointer-types] 传递“allocateMemory”的参数 3 allocateMemory(dim, &rows, &board); ^

编辑

对于遇到此问题并检查此页面的任何人,最后一次尝试实际上是正确的,正如迈克尔在下面回答的那样。错误是对应头文件的错误,在修复头文件时已经修复。

【问题讨论】:

allocateMemory(dim, &(*rows), &(*board)); 这与allocateMemory 的签名不匹配,您正在传递(int, int*, int**),但它需要(int, int**, int***) 我解决了这个问题,但在编辑中添加它不起作用 【参考方案1】:

让我们关注您的rows 变量:

rows 是一个指针,它是一个保存内存地址的变量。 现在您希望 alocateMemory 将内存块的地址写入rows,以保存您的数据。很简单:

size_d dim = 10;
int* rows = 0;
rows = calloc(1, sizeof(int) * dim);

但是,如果你把这段代码放到一个类似的函数中

void allocateMemory(size_t dim, int* rows) 
    rows = calloc(1, sizeof(int) * dim);

现在如果你像这样调用这个函数

int* actualRows = 0;
allocateMemory(3, actualRows);

actualRows(即0)的将被复制到您在allocateMemory 中操作的新变量rows 中。当你写入行时,它的值会发生变化,但是当留下allocateMemory 时,rows 将被销毁。 actualRows 永远不会被更改。

您想要的是allocateMemoryactualRows 的值设置为内存地址。为此,您必须向allocateMemory 提供actualRows地址,例如

allocateMemory(3, &actualRows);

&atualRowsactualRows的内存地址,它的类型是int**(指向int的指针)。

现在您必须适当地调整allocateMemory 的签名:

void allocateMemory(size_t dim, int** rows) 
    rows = calloc(1, sizeof(int) * dim);

而且,由于 rows 现在是一个指针,并且您想更改它的目标,因此您需要在分配它之前取消引用它:

*rows = calloc(1, sizeof(int) * dim);

总而言之:

void allocateMemory(size_t dim, int** rows) 
    *rows = calloc(1, sizeof(int) * dim);


...
int* actualRows = 0;
allocateMemory(3, &actualRows);
...

对于您的board,原则上相同。试试

#include <stdio.h>
#include <stdlib.h>

void allocateMemory(int dim, int** rows, int*** board) 
    *rows = calloc(dim * dim,sizeof(int));
    *board = calloc(dim, dim * sizeof(int*));

    if (rows == NULL || board == NULL) 
        printf("Error: calloc has failed\n");
    

    for(size_t i = 0; i < dim; ++i) 
        (*board)[i] = calloc(1, sizeof(int) * dim);

        if ((*board)[i] == NULL) 
            printf("Error: calloc has failed\n");
        
    



int main(int argc, char *argv[]) 

    size_t dim = 10;

    int *rows = NULL;
    int **board = NULL;
    allocateMemory(dim, &rows, &board);

    rows[0] = 10;
    rows[1] = 11;

    for(size_t i = 0; i < dim; ++i) 
        printf("%i ", rows[i]);
    

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

    board[0][0] = 11;
    board[9][0] = 99;
    board[9][9] = 101;

    for(size_t i = 0; i < dim; ++i) 

        for(size_t k = 0; k < dim; ++k) 

            printf("%i ", board[i][k]);
        
        printf("\n");
    

    printf("\n");

    for(size_t i = 0; i < dim; ++i) free(board[i]);
    free(board);

    free(rows);

【讨论】:

就像我上面解释的那样,首先尝试修复rows,然后继续修复board。顺便说一句,board 是一个包含dim 行和多少列的矩阵?或者board 应该是什么样子? int* rows = 0; 行是重新声明,你的意思是别的吗? 好的,板子的尺寸应该是dim *dim。还是在最后一段代码里有那个重新声明,但也看不懂它的初衷 它不能编译 :( 我在最后部分的 EDIT 部分添加了这个编译错误 试试我帖子末尾提供的代码的当前版本,能否提供编译错误?

以上是关于在 main 外部定义的函数内分配数组的主要内容,如果未能解决你的问题,请参考以下文章

C ++在函数内部分配动态数组[关闭]

c ++在类外部分配char数组的索引

C语言 外部函数引用

将二维数组复制到函数外部动态分配的二维数组

静态数组仅在类定义内溢出堆栈(段错误 11),否则不会......?

在函数中定义数组:float fltNum[10],该数组在内存中是如何被分配内存空间?何时被释放内存空间?c语言中