#c #linux #malloc #realloc
#c #linux #malloc #перераспределение
Вопрос:
Я разрабатываю функцию, в которой размер массива начинается с 10, если строка fgets больше, ему нужно выделить больше памяти, но я получаю сообщение об ошибке, когда строка слишком большая, например, если я набираю что-то с 15 символами, все в порядке, но с 30 я получаю ошибку! И я не знаю почему. Итак, я надеюсь, вы можете мне сказать.
-= РЕШАЕМАЯ В ЭТОМ КОДЕ =-
Мой основной:
char *buf;
shellExecute(amp;buf);
Мой код:
char* shellExecute(char** buf){
int bufSize = 10;
*buf = malloc(bufSize * sizeof(char));
if(*buf == NULL){
printf("[ERROR] can't malloc %d bytesn", bufSize);
exit(0);
}
char *readpos = *buf;
while (1){
fgets(readpos, bufSize, stdin);
/* Search from the end, as there's where the newline should be */
if (readpos[strlen(readpos)-1] == 'n'){
break;
}
/* Need to allocate more memory */
bufSize = bufSize;
*buf = realloc(*buf, *buf strlen(*buf) * sizeof(char));
/* Set the pointer to next position to read into */
readpos = *buf strlen(*buf);
/* Loop takes case of trying again */
}
}
Моя ошибка:
Комментарии:
1. Используйте отладчик и выполните пошаговый код….
2. Какой смысл передавать
char**
, если выreturn *buf
все равно это делаете?3. @KamilCuk Это не проблема, потому что у меня уже была функция void и все еще с ошибкой
4. Пожалуйста, не редактируйте вопрос и / или ответ с помощью вашего фиксированного кода. Они имеют смысл только тогда, когда речь идет о неправильном коде, и они могут помочь людям, у которых есть аналогичный неправильный код. Если вы хотите сообщить о том, как вы устранили проблему, опубликуйте вместо этого свой собственный ответ.
5. @NateEldredge Хорошо, спасибо
Ответ №1:
Общий размер начинается с 10. Вы делаете
fgets(readpos, bufSize, stdin);
На первой итерации readpos
указывает на начало буфера, так что это нормально. Допустим, считывается 9 байт, оставляя место для нулевого терминатора. Теперь вы делаете
bufSize = bufSize;
*buf = realloc(*buf, bufSize * sizeof(char));
Итак, сейчас bufSize
20 и *buf
имеет общий размер 20. Далее вы делаете
readpos = *buf strlen(*buf);
так что readpos
теперь указывает на *buf 9
.
Ваш следующий fgets
попытается прочитать 20 байт в буфер общего размера 20, но начиная со смещения 9, после которого доступно только 11 байт. Это может привести к переполнению буфера на 9 байт, вызывая неопределенное поведение.
Вероятно, вы хотите вести отдельный подсчет того, сколько байтов фактически было прочитано, и использовать это для вычисления оставшегося места в буфере, в который вы перейдете fgets
.
Другая ошибка заключается в том, что вам нужно проверить возвращаемое значение fgets
, чтобы определить, когда файл закончился или произошла ошибка. В нынешнем виде, когда происходит любая из этих вещей, ваша программа будет бесконечно зацикливаться.
Комментарии:
1. Итак, мне нужно переформулировать это
readpos = *buf strlen(*buf);
помещениеreadpos = *buf;
?2. @prt05: это позволит избежать переполнения буфера, но тогда вы будете перезаписывать ранее прочитанные данные новыми данными вместо добавления, что, я думаю, не то, что вы хотите.