Доступ к выделенной памяти без ошибки сегментации - PullRequest
0 голосов
/ 16 марта 2019

Я пытаюсь создать матрицу для игры в крестики-нолики.Я выделил для этого память, но не могу получить к ней доступ.Это показывает мне ошибку сегментации, и я не могу понять, почему.

   #include <stdio.h>
   #include <stdlib.h>

   //function to make a char matrix 
   void make_board (char** board)
   {
       board = malloc(sizeof(char*)*3);
       for(int i=0;i<3;i++)
       {
           board[i] = malloc(sizeof(char)*3);
       }
       for(int i=0;i<3;i++)
       {
           for(int j=0;j<3;j++)
           {
               board[i][j]='x';
           }
       }
   }

    //main function
    int main ()
    {
        char ** board;
        make_board(board);

        /*when i try to access it it show me a segmentation fault*/
        printf("%c\n",**board);
    }

Ответы [ 2 ]

1 голос
/ 16 марта 2019

Причина, по которой ваш код вызывает ошибку сегментации, связана с тем, как вы передаете указатель на массив символов в вашу функцию.В make_board, переназначая переменную board с помощью malloc, вы говорите компьютеру: «Make board указывает на массив символов».Это звучит так, как будто это будет работать, но когда вы делаете это, вы только переназначаете переменную board в make_board.В основном, доска переменных остается нетронутой, поскольку переменные копируются в функции в c, а не передаются с возможностью редактирования.Другая проблема с вашим кодом заключается в том, что вы никогда не инициализируете переменную board до того, как передадите ее в make_board, поэтому вы передаете 0x0 или, как интерпретируется компьютером, ничего.

Чтобы помочь вам понять, это игра за игрой того, что компьютер делает в этой программе (имейте в виду, это предполагает, что вы добавляете строку, которая выделяет доску в main):

  • Шаг 1: (ввод основного) Пользователь хочет использовать символ ** с именем board.Я выделю его так, чтобы он указывал на адрес 0x1234123412341234.
  • Шаг 2: Хорошо, теперь я должен передать board в make_board.(имейте в виду, что он передает 0x1234123412341234 и больше ничего).
  • Шаг 3: (вход в make_board) Хорошо, пользователь хочет выделить board для 3 типов char *, поэтому я назначу board для 0x1234567812345678.

Здесь все пошло не так.Остальная часть вашего кода работает, но при повторном вводе main плата остается 0x1234123412341234, а не 0x1234567812345678.Таким образом, когда вы печатаете ** board, он никогда не назначается и не указывает ни на что, вызывая ошибку сегментации.

Вот мой код, который исправляет это, передавая char ***, board_ptr, что позволяет make_board создавать символ **, на который указывает его параметр, без изменения.

#include <stdio.h>
#include <stdlib.h>

//function to make a char matrix
void make_board(char*** board_ptr)
{
        *board_ptr = calloc(3, sizeof(char*));
        char **board = *board_ptr;
        for (int i = 0; i < 3; i++) {
                board[i] = calloc(3, sizeof(char));
        }
        for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                        board[i][j]='x';
                }
        }
}

//main function
int main(int argc, char *argv[])
{
        char ***board_ptr = calloc(1, sizeof(char**));
        char **board;

        make_board(board_ptr);
        board = *board_ptr;

        printf("%c\n", **board);/* Now it works! */
}
0 голосов
/ 16 марта 2019

Вы изменяете переменную board внутри make_board, но передаете ее по значению, чтобы она не изменялась в основной функции.Вы пытаетесь напечатать переменную board, которая была инициализирована с мусором, таким образом, вы получили ошибку сегментации.Вы должны вернуть указатель с make_board: char **board = make_board().Или передайте переменную платы по указателю: make_board(&board)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...