首页 > 解决方案 > 在 main 外部定义的函数内分配数组

问题描述

我正在尝试在函数内的数组上使用 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(dim, &rows, &board) 传递 'allocateMemory' 的参数 2 ); ^" 错误:从不兼容的指针类型传递 'allocateMemory' 的参数 3 [-Werror=incompatible-pointer-types] allocateMemory(dim, &rows, &board); ^

编辑

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

标签: cpointerscalloc

解决方案


让我们关注您的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);

(即)的将被复制到您在其中操作的新变量中。当你写入行时,它的值会发生变化,但是当你离开时,就会被销毁。永远不会改变。actualRows0rowsallocateMemoryallocateMemoryrowsactualRows

你想要的是allocateMemory设置actualRowsoa 内存地址的值。为此,您必须提供类似allocateMemory地址actualRows

allocateMemory(3, &actualRows);

&atualRows是的内存地址,actualRows它的类型是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);
}

推荐阅读