#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?