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

Меня очень беспокоят строки в 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? */

person Arturs Vancans    schedule 20.11.2011    source источник
comment
Обратите внимание, что если вы объявляете char [257], индекс изменяется от 0 до 256.   -  person Aurelio De Rosa    schedule 20.11.2011


Ответы (5)


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

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

person JosephH    schedule 20.11.2011

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

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

person Michael Price    schedule 20.11.2011
comment
Это \0 (NUL), а не NULL. - person Fred Foo; 20.11.2011
comment
И все же NULL, 0 и '\ 0' имеют разные значения. Нет необходимости объединять их только потому, что язык, разработанный 30 лет назад, позволяет это сделать. - person John Zwinck; 20.11.2011
comment
Необязательно, NULL можно определить как ((void*)0). В любом случае это разные концепции, которые не следует объединять. - person Fred Foo; 20.11.2011
comment
@larsmans - Ах, да, NULL может быть 0 преобразованием в void*, поэтому это может не сработать. - person Michael Price; 20.11.2011
comment
Ваше утверждение о массивах зависит от того, как он инициализирован. Рассмотрим char str [4] = test vs char str [] = test. - person Wiz; 20.11.2011

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

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

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

person Basile Starynkevitch    schedule 20.11.2011

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

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, что затрудняет освобождение памяти.

person RobotNinja    schedule 20.11.2011

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

person Adrián Pérez    schedule 20.11.2011
comment
strncpy - довольно специальная функция со специальной семантикой. К сожалению, обычно это не то, чего хотят люди, когда они просто копируют строки. - person John Zwinck; 20.11.2011