Как вернуть матрицу (2D-массив) из функции? (С)

Я создал функцию, которая генерирует бинго-плату, и я хочу вернуть плату бинго.

чего я не ожидал, он не работает.

вот функция:

int** generateBoard() {
    int board[N][M], i, j , fillNum;
    Boolean exists = True;
    // initilize seed
    srand(time(NULL));
    // fill up..
    for(i = 0; i < N; ++i) {
        for(j = 0; j < M; ++j) {
            exists = True;
            while(exists) {
                fillNum = rand()%MAX_RANGE + 1; // limit up to MAX_RANGE
                if(beenAdded(board, fillNum) == Exist) {
                    continue;
                } else {
                    board[i][j] = fillNum;
                    exists = False;
                }
            }
        }
    }
    return board;
}

У меня есть ошибка компиляции (красная сублиния) на линии "возврат платы".

есть способ вернуть 2D-массив без, используя structs\dynamic allocations?

Я использую Microsoft Visual С++ Express 2010.

Ответы

Ответ 1

Кто-то должен владеть памятью этой доски где-то, и что еще более важно, что право собственности должно вернуться к вызывающей стороне этой функции. Без динамического распределения ваша единственная другая реальная альтернатива - отправить ее в функцию как в параметр in/out.

void generateBoard(size_t N, size_t M, int board[N][M])
{
    int i, j , fillNum;
    Boolean exists = True;
    // initilize seed
    srand(time(NULL));
    // fill up..
    for(i = 0; i < N; ++i) {
        for(j = 0; j < M; ++j) {
            exists = True;
            while(exists) {
                fillNum = rand()%MAX_RANGE + 1; // limit up to MAX_RANGE
                if(beenAdded(board, fillNum) == Exist) {
                    continue;
                } else {
                    board[i][j] = fillNum;
                    exists = False;
                }
            }
        }
    }
}

и вызовите это со своего вызывающего абонента:

int main()
{
    const size_t N = 10;
    const size_t M = 10;
    int board[N][M];

    generateBoard(N,M,board);

    ...
}

Я также хотел бы переустановить вызов srand() на код запуска в main(). В идеале он никогда не должен быть в какой-либо потенциально повторяющейся функции, и должен гарантировать, что будет выполняться только один раз за выполнение каждого процесса. (примечание: я, честно говоря, не помню, если это один раз для выполнения потока, но на данный момент в вашей кривой обучения кодированию я предполагаю, что многопоточность еще не включена в радар).

Наконец, ваш цикл произвольного заполнения бесполезен для повторения. Существуют лучшие альтернативы, генерирующие то, что вы, по-видимому, пытаетесь сделать: создать произвольную перестановку существующего набора чисел. Как написано, вы можете некоторое время прокручивать попытки заполнить эти последние несколько слотов, в зависимости от того, насколько больше MAX_RANGE сравнивается с (N*M).

Ответ 2

Вы определили board как локальную переменную - ее память связана с тем, что функция выходит за пределы области видимости.

Вы можете объявить плату глобальной или создать ее динамически следующим образом:

int **allocate_board(int Rows, int Cols)
{    
    // allocate Rows rows, each row is a pointer to int
    int **board = (int **)malloc(Rows * sizeof(int *)); 
    int row;

    // for each row allocate Cols ints
    for (row = 0; row < Rows; row++) {
        board[row] = (int *)malloc(Cols * sizeof(int));
    }

    return board;
}

Вам нужно будет динамически освободить плату:

// you must supply the number of rows
void free_board(int **board, int Rows) 
{
    int row;

    // first free each row
    for (row = 0; row < Rows; row++) {
         free(board[row]);
    }

    // Eventually free the memory of the pointers to the rows
    free(board);
 }