2017-02-23 22 views
0

Я начинаю с C, и я немного запутался в указателях и о том, как они передаются другим функциям. Я работаю над проектом и в своей основной функции, я malloc 2D-массив символов, представляющих игровое поле.Пытается получить доступ к адресу 2D-массива в C и получить ошибку сегментации

// In main, allocate 2D array 
char **board = malloc(rows * sizeof(char*)); 
for (int i = 0; i < rows; i++) { 
    board[i] = malloc(cols * sizeof(char)); 
} 

Функция может быть вызван позже, которая будет загружать сохраненную версию игры, и, таким образом, повторно таНос моих переменных плат.

void stringToGame(char ***board, int *rows, int *cols, int *turn, int *winLength) { 
    // Set new values for rows and cols based on file 
    ... 

    // Malloc board 
    *board = malloc(*rows * sizeof(char*)); 
    for (int i = 0; i < *rows; i++) { 
     *board[i] = malloc(*cols * sizeof(char)); 
    } 

} 

Когда я вызываю метод stringToGame в своей основной функции, я передаю адрес платы.

stringToGame(&board, &rows, &cols, &turn, &winLength); 

Передача адреса платы вызывает ошибку сегментации, и я понятия не имею, почему.

В качестве второстепенного вопроса мне нужно освободить() мой старый 2D-массив для доски, прежде чем я буду malloc новым?

+0

Это упростит управление вашим кодом, если у вас есть выделенная функция для распределения/перераспределения платы. –

+0

@ M.M Это план, как только я смогу заставить его работать вообще! –

ответ

1

Это

*board[i] = malloc(*cols * sizeof(char)); 

должен быть

(*board)[i] = malloc(*cols * sizeof(char)); 

, потому что индекс массива оператор [] имеет более высокий приоритет, чем оператор косвенного * и, следовательно, будет выполнять первый, но вам нужно обратное произойдет, т.е. сначала *, затем [i].

0

Во-первых, то, что вы заявили, не является 2-d array, это двойной указатель. Между этими двумя есть difference.

Во-вторых, вам не нужно передавать адрес массива функции, так как массивы передаются по ссылке anyways. Вы можете просто передать двойной указатель на свою функцию после malloc-it.

stringToGame(board, &rows, &cols, &turn, &winLength); 

И ответ на ваш вопрос второстепенный, да, вы должны free свой старый указатель первым, прежде чем вы таНос его снова, в противном случае ваша программа будет иметь место утечка памяти. Первое значение board будет потеряно, и вы не сможете его освободить.

+1

Функция 'stringToGame' перераспределяет плату, поэтому передача' board' по значению не будет работать –