返回由malloc分配的数组

时间:2017-03-20 21:08:38

标签: c arrays

我在main.c中有代码:

 int main(void)
 {
    int* sudokuBoard = getBoard();
    printBoard(sudokuBoard, 9);

    return 1;
 }

我还有另一个文件中的下一个代码:

 int* getBoard()
 {  
   int i;
   int **Board = (int**)malloc(9 * sizeof(int*));
   for (i = 0; i < 9; i++)
   {
      Board[i] = (int*)malloc(9 * sizeof(int));
   }
   int prototype[9][9] =
   {
    { 0,0,1,0,0,0,0,0,9 },
    { 0,3,0,0,0,0,5,4,0 },
    { 0,0,0,0,0,0,0,0,0 },
    { 0,0,0,2,0,0,0,8,0 },
    { 2,0,0,0,6,7,0,0,0 },
    { 0,0,0,0,0,0,0,1,0 },
    { 0,9,0,0,0,0,0,0,0 },
    { 0,0,0,9,0,0,2,0,0 },
    { 0,0,0,0,4,0,0,0,0 },
   };

   for (i = 0; i < 9; i++)
   {
    Board[i] = prototype[i];
   }

   return &Board[0][0];
 }

 void printBoard(int* arr, int size)
 {
   int i, j;
   printf("BOARD:\n");
   for (i = 0; i < size; i++)
   {
    for (j = 0; j < size; j++)
    {
        printf("%d ", *(arr + i*size + j));
    }
    printf("\n");
   }
   printf("\n----------------\n");
 }

问题是当我尝试打印我的数组时(有奇怪的数字而不是数组值)。如何在一个函数中创建数组并将其返回到另一个函数然后打印它?

2 个答案:

答案 0 :(得分:1)

在这个循环中

for (i = 0; i < 9; i++)
{
   Board[i] = (int*)malloc(9 * sizeof(int));
}

分配了9个内存区域,指针Board [i]按其地址初始化。

在这个循环中

for (i = 0; i < 9; i++)
{
    Board[i] = prototype[i];
}

指针被重新分配。结果,函数中存在内存泄漏。

此外,指针现在指向本地数组的元素,退出函数后将无效。

不必重新分配指针,而是必须将本地数组的元素复制到新分配的数组中。

还完全不清楚为什么要尝试将函数声明为返回类型int *而不是正确的返回类型int **

同样,当数组的大小固定时,您可以分配一个二维数组,如

int ( *Board )[9] = malloc( int[9][9] ); 

答案 1 :(得分:0)

在过去的几个月里,我一直在努力学习C语言,所以我采取了一些措施来汲取你的代码并稍微修改一下并修复你的问题。我留下了解释更改/修复的评论。看起来其他人已经提供了答案,但我很乐意使用您的代码。如果有人在我的代码中发现任何问题,请告诉我,希望了解更多信息!

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <stdint.h>
#include <inttypes.h>
#include <assert.h>

// Instead of hard coding the board size, we can let the getBoard function
// inform the caller the number of rows and columns. Also, we can use
// int8_t instead of int to ensure cross platform consistency
int8_t *getBoard(int8_t *rows, int8_t *cols) {

    // Make sure the caller passed in what we need
    assert(rows /* rows should not be NULL*/);
    assert(cols /* cols should not be NULL*/);

    *rows = 9;
    *cols = 9;

    int8_t prototype[9][9] = {
        { 0,0,1,0,0,0,0,0,9 },
        { 0,3,0,0,0,0,5,4,0 },
        { 0,0,0,0,0,0,0,0,0 },
        { 0,0,0,2,0,0,0,8,0 },
        { 2,0,0,0,6,7,0,0,0 },
        { 0,0,0,0,0,0,0,1,0 },
        { 0,9,0,0,0,0,0,0,0 },
        { 0,0,0,9,0,0,2,0,0 },
        { 0,0,0,0,4,0,0,0,0 },
    };

    int8_t *board = malloc(sizeof(prototype));

    // Instead of iterating through the prototype we can memmove the contents
    memmove(board, prototype, sizeof(prototype));

    return board;
}

// Because we don't have the row and column count hardcoded anymore, we have to
// pass in the count to our print function.
void printBoard(int8_t *arr, int8_t rows, int8_t cols) {
    // puts gives you the "\n" at the end "for free"
    puts("BOARD:");

    // We don't have to pre-declare our iterator variables anymore in modern C.
    for (int8_t y = 0; y < rows; y++) {
        for (int8_t x = 0; x < cols; x++) {

            // Seperating out the pointer math makes it easier to look at
            int8_t *column = arr + y * cols;
            int8_t n = *(column + x);

            // We can use the formatters provided by inttypes.h to again ensure consistency
            printf("%" PRId8 " ", n);
        }

        printf("\n");
    }
}

int main(int argc, const char * argv[]) {
    // getBoard now gives us the counts of the board
    int8_t rows = 0;
    int8_t cols = 0;

    int8_t* sudokuBoard = getBoard(&rows, &cols);

    // We'll pass the counts into the print function
    printBoard(sudokuBoard, rows, cols);

    // Because getBoard malloc'd the board, we need to free it
    free(sudokuBoard);

    return 0;
}