Перераспределяемый указатель не был выделен, установите точку останова в malloc_error_break на debug

#c #xcode #gcc

#c #xcode #gcc

Вопрос:

Я разрабатывал эту очень простую игру на C в Windows, где я использовал команду gcc matches.c -o ./matches для ее компиляции. Я импортировал код на свой Mac и перекомпилировал его с помощью gcc и clang . Используя оба метода, программа полностью вылетает, иногда закрывая мой сеанс терминала, и выводит это.

 matches(54122,0x1137715c0) malloc: *** error for object 0x7ffee9e8ba40: pointer being realloc'd was not allocated
matches(54122,0x1137715c0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6

Broadcast Message from _appleevents@(myname).local                                
        (no tty) at 20:33 CET...                                               

matches(54122,0x1137715c0) malloc: *** error for object 0x7ffee9e8ba40: pointer
 being realloc'd was not allocated
  

В Windows код был полностью исправлен без ошибок.

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

Кстати, вот код. Программа завершает работу в функции установки при getline()

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

void show_matches(int n);
void setup(int *numberOfPlayersA, int *gamemodeA, int *numberOfMatchesA);
void changePlayersTurn(int *currentPlayerA, int numberOfPlayers);
int random_move();

int main(void) {
  char *input;
  int currentPlayer = 1;
  size_t n = 0;
  int numberOfPlayers = 0;
  int gamemode = 0;
  int numberOfMatches = 0;
  int move = 0;

  setup(amp;numberOfPlayers, amp;gamemode, amp;numberOfMatches);
  show_matches(numberOfMatches);

  while (numberOfMatches >= 1) {
    printf("33[1;31m");
    printf("nnPlayer %d> ", currentPlayer);
    printf("33[0m");

    if (gamemode == 2 || currentPlayer == 1) {
      getline(amp;input, amp;n, stdin);
      move = atoi(input);

      if (move > 3 || move < 1 ) {
           move = 1;
      }
    } else {
      int randomMove = random_move();
      move = randomMove;
      printf("%d", randomMove);
    }



    numberOfMatches -= move;
    show_matches(numberOfMatches);


    if (numberOfMatches >= 1) {
      changePlayersTurn(amp;currentPlayer, numberOfPlayers);
    }
  }


  printf("nnPlayer %d lostnn", currentPlayer);

  return 0;
}

void setup(int *numberOfPlayersA, int *gamemodeA, int *numberOfMatchesA) {
  char *input;
  size_t n = 0;

  printf("--The matches--nn");
  printf("Do you plan on playing against:nt1. The computernt2. Other personsnn(1 / 2) > ");
  getline(amp;input, amp;n, stdin);
  printf("1");
  *gamemodeA = atoi(input);
  printf("2");
  if (*gamemodeA == 2) {
    printf("nnPlease enter the number of players: ");
    getline(amp;input, amp;n, stdin);
    *numberOfPlayersA = atoi(input);
  }
  printf("Enter the number of matches: ");
  getline(amp;input, amp;n, stdin);
  *numberOfMatchesA = atoi(input);
  *numberOfPlayersA = 2;
  printf("4");
}

void changePlayersTurn(int *currentPlayerA, int numberOfPlayers) {
  if (*currentPlayerA == numberOfPlayers) {
    *currentPlayerA = 1;
  } else {
    *currentPlayerA  = 1;
  }
}

void show_matches(int n) {
  for (int i = 0; i < n; i  ) {
    printf("|");
  }
}

int random_move() {
  int num = (rand() % (3 - 1   1))   1;
  return num;
}
  

Комментарии:

1. Этим я хочу ответить, я точно знаю, что ошибка сохраняется

2. Вы должны проверить возвращаемое значение из getline , как и в любой функции пользовательского ввода.

3. @DiegoROJAS вы пропустили инициализацию ввода , вот почему у вас ошибка, некоторые свободные также отсутствуют, смотрите Мой ответ

Ответ №1:

В главном :

  char *input;
 ...
 getline(amp;input, amp;n, stdin);
  

вы вызываете getline без инициализации ввода, если (неопределенное) значение не равно NULL, getline освободит его, и поскольку это не адрес выделенного блока, у вас возникает ошибка

вам нужно, например :

   input = NULL;
  getline(amp;input, amp;n, stdin);
  move = atoi(input);

  if (move > 3 || move < 1 ) {
       move = 1;
  }
  free(input);
  

У вас аналогичная ошибка в настройке :

 char *input;
...
getline(amp;input, amp;n, stdin);
...
getline(amp;input, amp;n, stdin);
  

вам нужно установить для ввода значение NULL перед первым вызовом getline, и вам нужен свободный после последнего вызова, например :

 char *input;
...
input = NULL;
getline(amp;input, amp;n, stdin);
...
getline(amp;input, amp;n, stdin);
*numberOfMatchesA = atoi(input);
free(input);
  

Дополнительные замечания :

  • вы пропустили проверку результата getline
  • использование atoi небезопасно, вы получаете 0, если пользователь вводит что-то неправильно, лучше использовать strtod или sscanf
  • в основном вместо принудительного ввода 1 при вводимом значении, если оно не находится между 1 и 3, кажется, лучше повторить ввод

Комментарии:

1. Большое вам спасибо за ваш очень подробный и четкий ответ. У вас есть какие-либо идеи, почему программа не вылетает в Windows?