Вы не обнаруживаете EOF надежно. Вам нужно сохранить результат getchar()
в int
, а не char
. И вы не должны пытаться хранить EOF
в своем буфере.
Вы не проверяете распределение памяти.
Вы не нуль, завершающий выходную строку, поэтому printf()
в main()
может привести к сбою.
Вы кого-то сбиваете с толку (может быть, меня, может быть, компилятора, может быть, самого себя), выделяя 51 байт и говоря функции, что у нее есть только 50 байтов для игры.
И, в частности, вы должны использовать *buff
в большинстве точек внутри функции, в том числе, в частности, при добавлении символа:
(*buff)[length++] = c;
Вам действительно следует уделять больше внимания всем этим предупреждениям компилятора. Если ваш компилятор не дает вам ничего, получите лучший компилятор (или включите флаги предупреждения - но компилятор должен кричать на вас в режиме по умолчанию).
Кроме того, вы неправильно называете realloc()
по трем причинам. Одним из них является проблема *buff
. Во-вторых, вы хотите, чтобы размер был k
, а не start_size + 1
. Во-вторых, вы присваиваете результат входному параметру. Это «нет-нет», потому что, если выделение не удается, вы теряете указатель на ранее (и все еще) выделенные данные. Всегда используйте идиому:
void *new_data = realloc(old_data, new_size);
if (new_data == 0)
...deal with out of memory error...
else
{
old_data = new_data;
old_size = new_size;
}
Применительно к вашему коду это означает:
char *new_buff = (char *)realloc(*buff, k); // NOT start_size+1!!!
if (new_buff == 0)
...deal with out of memory error...
else
*buff = new_buff;
Есть те, кто возражает против броска на malloc()
и realloc()
и calloc()
; есть те, кто предпочитает присутствующие слепки. С обеих сторон есть аргументы разной степени обоснованности. Я предпочитаю актерский состав - я уважаю тех, кто предпочитает без актерского состава. Мы приходим к разным выводам по разным причинам.
Я не изучал код для других ошибок 'off-by-one'. Подозреваю, что их тоже может быть несколько.
person
Jonathan Leffler
schedule
15.01.2012