Подтвердить что ты не робот

Когда printf ( "% s", char *) прекращает печать?

В моем классе мы пишем собственную копию функции C malloc(). Чтобы протестировать мой код (который в настоящее время может выделить пространство в порядке), я использовал:

char* ptr = my_malloc(6*sizeof(char));
memcpy(ptr, "Hello\n", 6*sizeof(char));
printf("%s", ptr);

Вывод обычно будет таким:

Hello
Unprintable character

Некоторая отладка показала, что мой код не вызывает этого как такового, поскольку память ptr выглядит следующим образом:

[24 байта метаинформации] [Количество запрошенных байтов] [Заполнение]

Итак, я понял, что printf добирается до прокладки, которая является просто мусором. Поэтому я проверил тест: printf("%s", "test\nd"); и получил:

test
d

Что заставляет меня задаться вопросом, когда DOES printf ( "% s", char *) останавливает печать символов?

4b9b3361

Ответ 1

Он останавливает печать при достижении нулевого символа (\0), потому что %s ожидает, что строка будет завершена с нулевым значением (т.е. ожидает, что аргумент будет строкой C).

Строковый литерал "test\nd" имеет нулевое завершение (все строковые литералы имеют нулевое завершение). Однако ваш массив символов ptr не потому, что вы копируете только шесть символов в буфер (Hello\n), и вы не копируете седьмой символ - нулевой терминатор.

Ответ 2

Джеймс прав насчет остановки печати, когда он получает нулевой символ, и Uri правильно, что вам нужно выделить 7-символьный буфер для хранения "hello\n".

Некоторая путаница с терминаторами будет уменьшена, если вы использовали обычную C-идиому для копирования строки: strcpy(ptr, "Hello\n"), а не memcpy.

Также, по определению, sizeof (char) == 1 в C, поэтому 6*sizeof(char) является избыточным

Ответ 3

Строки C заканчиваются на нуль (там есть символ \0 в конце), что C знает, когда прекращать печать или работать с буфером в виде строки. Вы несете ответственность за то, чтобы никогда не ставить строку в более длинном пространстве, чем то, что вы выделили.

Обратите внимание, что Hello\n не является шестью символами, это фактически строка из семи символов. Вы используете пять для Hello, один для новой строки и один для нулевого терминатора.

Попытка вместить 7 символов в буфер с шестью символами считается ошибкой, я не уверен, что она отвечает за проблемы, которые у вас есть в настоящее время, но похоже, что копирование 6 символов не будет копировать нулевой ограничитель. Поэтому я бы предпочел, чтобы ваш отпечаток вышел за пределы Hello и в какой-то настоящий мусор.

Ответ 4

когда он достигает нуля. вам нужно 7 символов.