在main之外的main中分配一个函数中的数组

时间:2018-05-20 14:54:10

标签: c pointers calloc

我尝试在函数内部使用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相同)并且没有编译错误: "错误:传递' allocateMemory'的参数2来自不兼容的指针类型[-Werror = incompatible-pointer-types]   allocateMemory(dim,& rows,& board);                       ^" 错误:传递' allocateMemory'的参数3来自不兼容的指针类型[-Werror = incompatible-pointer-types]   allocateMemory(dim,& rows,& board);                              ^

修改

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

1 个答案:

答案 0 :(得分:0)

让我们关注您的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)将被复制到您在rows中操作的新变量allocateMemory中。当您写入行时,其值会更改,但在保留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 = 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);
}