Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Строка с завершающим нулем в C

Автор вопроса: Arturs VancansОтветов: 5

Меня очень беспокоят строки в C. Нужно ли мне устанавливать последний символ \ 0 или он делает это сам? Если я не делаю этого вручную, то когда я пытаюсь отладить код и когда я обращаюсь к string1 [257], он не равен нулю. У меня проблемы с освобождением выделенной памяти для массива строк, поэтому я подумал, что это причина.

char string1[257], string2[257];
scanf("%s", &string2);
string1[257] = '\0';
strncpy(string1, string2, 257);
string1[257] = '\0'; /* do I need to do that? */
  • Обратите внимание, что если вы объявляете char [257], индекс изменяется от 0 до 256. Aurelio De Rosa 20.11.2011

cnullstring

Ответы

Ответ 1 · рейтинг 2 · JosephH

Это абсолютно необходимо? Нет, потому что, когда вы вызываете scanf, strcpy (за исключением strncpy, где вам нужно вручную поставить ноль, если он превышает размер), он копирует нулевой терминатор за вас. В любом случае это хорошо? Не совсем, это не помогает решить проблему переполнения буфера, поскольку эта функция в любом случае превысит размер буфера. Тогда как лучше всего? используйте c ++ с std::string.

Между прочим, если вы обращаетесь / пишете в string1[257], он будет недоступен, поскольку вы обращаетесь / записываете элемент 258-го в массив размером 257. (это индекс, основанный на 0).

Ответ 2 · рейтинг 2 · Michael Price

Строковые литералы, такие как "Hello World!", заканчиваются нулем, но массивы char не заканчиваются автоматически нулем.

Общий принцип, который я всегда придерживался, - проявлять особую осторожность и назначать '\0' в конец строки, если это не вызывает проблем с производительностью. В таких случаях я очень внимательно выбираю, какие библиотечные функции использую.

Ответ 3 · рейтинг 2 · Basile Starynkevitch

Литеральная строка, такая как "foo\nbar", всегда преобразуется в const char literal[] с дополнительным нулевым байтом в конце. (Таким образом, константа будет иметь 8 байтов, первый - f, а последний - ноль).

Но вы правы, когда явно устанавливаете последний байт в 0 после strncpy.

И, как заметил Аурелио де Роса, последний правильный индекс - 256 для массива [257].

Ответ 4 · рейтинг 1 · RobotNinja

Всегда будьте осторожны, чтобы выделить достаточно памяти для строк, сравните эффекты следующих строк кода:

char s1[3] = "abc";
char s2[4] = "abc";
char s3[] = "abc";

Все три считаются допустимыми строками кода (http://c-faq.com/ansi/nonstrings.htmlhttp://c-faq.com/ansi/nonstrings.html), но в первом случае не хватает памяти для четвертого символ с завершающим нулем. s1 не будет вести себя как обычная строка, но s2 и s3 будут. Компилятор автоматически подсчитывает s3, и вы получаете четыре байта выделенной памяти. Если вы попытаетесь написать

s1[3] = '\0';

это неопределенное поведение, и вы записываете в память, которая не принадлежит s1, и это может иметь странные эффекты, возможно, даже нарушая внутреннюю информацию malloc, что затрудняет освобождение памяти.

Ответ 5 · рейтинг 1 · Adrián Pérez

Да, вам нужно это сделать. Не все функции помещают вам нулевой символ, а strncpy, как я могу прочитать на его странице руководства, требует наличия нулевого байта среди первых n символов src.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы