Строка C в конце '\ 0' - PullRequest
       8

Строка C в конце '\ 0'

0 голосов
/ 18 сентября 2018

При написании c-кода я пытался написать strcpy собственный код, и я столкнулся с этой проблемой.

#include <stdio.h>
#include <string.h>

void strcpy2(char *s, char *t);

int main() {
    char a[10] = "asds";
    char b[10] = "1234567890";

    strcpy2(a, b);
    printf("Copy completed! : %s", a);
    return 0;
}

void strcpy2(char *s, char *t) {
    while ((*s++ = *t++));
}

Код ошибки: процесс завершен с кодом выхода -1073741819 (0xC0000005)

Благодаря этому вопросу в s.o я узнал, что строка должна заканчиваться на '\ 0', но почему приведенный выше код не работает, даже если он не вызывает ошибки при объявлении? (Это хорошо работало, когда char b [10] = "123456789")

Итак, как именно '\ 0' влияет на этот процесс и в конечном итоге вызывает ошибку? (Время выполнения? Время компиляции и т. Д.) (Я только знаю, что '\ 0' должно быть концом строки)

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

В строке char b[10] = "1234567890"; строковый литерал "1234567890" составляет ровно 10 символов + 1 нулевой терминатор.В массиве не осталось места, поэтому он не завершается нулем.

Обычно компилятор предупреждает вас о предоставлении слишком большого инициализатора, но этот конкретный случай представляет собой особую ловушку.В правилах инициализации стандарта C мы находим это маленькое злое правило (C17 6.7.9 §14, выделение мое):

Массив типа символов может быть инициализирован литералом строки символов или UTF−8 строковый литерал, необязательно заключенный в фигурные скобки.Последовательные байты строкового литерала (включая завершающий нулевой символ , если есть место или массив неизвестного размера), инициализируют элементы массива.

Неткомната в вашем случае, так что вы не получите нулевой символ.И из-за этого странного небольшого правила компилятор также не предупреждает об этом, потому что код соответствует стандарту C.

0 голосов
/ 18 сентября 2018

char b[10] = "1234567890"; не содержит NUL-терминатор, поэтому

while ((*s++ = *t++));

завершается некорректно (формально поведение программы undefined ).Обратите внимание, что константа "1234567890" имеет тип char[11];компилятор позволяет назначать его меньшему массиву, элементы которого удаляются автоматически.

...