Пособие по практике программирования

       

Никогда не следует употреблять gets,





Никогда не следует употреблять gets, поскольку не существует способа ограничить размер вводимой информации. Это ведет к проблемам, связанным с безопасностью, к которым мы вернемся в главе 6; там мы увидим, что всегда лучше использовать fgets. Однако существует и еще одна проблема: функция strlen вычисляет размер строки, не учитывая завершающего строку символа ' \0', а функция st rcpy его копирует. Таким образом, выделяется недостаточно места, и st rcpy пишет за пределами выделенной памяти. Стандартной формой является следующая:
р = malloc(strlen(buf)+1);
strcpy(p, buf);
или
р = new char[strlen(buf)+1];
strcpy(p, buf);
в C++. Таким образом, если вы не видите +1, то стоит проверить все еще раз.
В Java такой проблемы нет, поскольку строки там не представляются в виде массивов, оканчивающихся на 0. Кроме того, индексы массивов проверяются, так что в Java выйти за границы массива невозможно.
В большинстве сред С и C++ предусмотрена библиотечная функция strdup, которая создает копию строки, используя для этого malloc и st rcpy, что гарантирует от обсуждавшейся чуть выше ошибки. К сожалению, st rdup не входит в стандарт ANSI С.
Кстати говоря, ни в первой, ни в окончательной версии не проверяется значение, возвращаемое функцией malloc. Мы опустили эту проверку для того, чтобы сфокусировать ваше внимание на теме данного раздела, однако в настоящей программе значения, возвращаемые функциями malloc, realloc, strdup, а также другими функциями, выделяющими память, должны в обязательном порядке проверяться.
Используйте цепочки else-if для многовариантных ветвлений. Стандартной формой записи многовариантного ветвления является последовательность операторов if. . .else if...else:

Содержание раздела