Выделите массив в main внутри функции, которая определена вне main - PullRequest
0 голосов
/ 20 мая 2018

Я пытаюсь использовать 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 не компилируется с ошибкой: "ошибка: передача аргумента 2 для allocateMemory из несовместимого типа указателя [-Werror = incompatible-pointer-types] allocateMemory (dim, & columns, & board); ^ "ошибка: передача аргумента 3 для allocateMemory из несовместимого типа указателя [-Werror= несовместимые типы-указатели] allocateMemory (dim, & lines, & board);^

РЕДАКТИРОВАТЬ

Для тех, кто сталкивается с этой проблемой и проверяет эту страницу, эта последняя попытка на самом деле верна, как Майкл ответил ниже.Ошибки относятся к ошибке в соответствующем заголовочном файле и были исправлены при исправлении заголовочного файла.

1 Ответ

0 голосов
/ 20 мая 2018

Давайте сосредоточимся на вашей переменной 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);

The значение из actualRows (а именно 0) будет скопировано в новую переменную rows, которой вы манипулируете в allocateMemory.Когда вы записываете в строки, его значение изменяется, но когда остается allocateMemory, rows будет уничтожено.actualRows никогда не будет изменено.

То, что вы хотите, это то, что allocateMemory устанавливает значение actualRows адрес памяти.Для этого вам необходимо предоставить allocateMemory адрес из actualRows, например

allocateMemory(3, &actualRows);

&atualRows - адрес памяти actualRows и его тип 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);
}
...