'\0' в конце строки, так ли он нужен?

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

int main()
{
    char* src = strdup("Hello!");
    int len = strlen(src);
    char* dest = (char*) malloc(len);
    memcpy(dest, src, len);
    int len2 = strlen(dest);
    printf("Destination: %s %d\nSource: %s\n", dest,len2, src);
    printf("Source: %s", src);
    do
    {
        printf("-- %c\n", *dest);
    }while(*dest++ != '\0');
    return 0;    
}

Как вы можете заметить в memcpy я не копирую '\0' но тем не менее цикл while не бесконечный и выводит всю строку без мусора. Так вот, есть ли в этом коде ошибка, должен ли я добавлять '\0' к скопированной строке? Есть ли ситуации когда добавлять '\0' не обязательно? Я хочу понять, либо строка так в памяти удачно раполагается, что '\0' за пределами строки лежит, либо я чего-то не понимаю, либо компилятор очень умный. Объясните, почему я не получаю бесконечный цикл.


Ответы (2 шт):

Автор решения: Harry

Понимаете, у вас сейчас получился примерно следующий рассказ.

Мне всю жизнь говорят, что переходить на красный свет нельзя. Но посмотрите - я перешел на красный. Затем перебежал на красный. Затем даже переполз - и ничего! Я жив, я не в больнице!

Так, может переходить дорогу на зеленый - не обязательно?

У вас в любом случае наблюдается выход за границы выделенной памяти - нулевой символ уже за пределами выделенной malloc памяти, а значит, это undefined behavior и говорить больше не о чем. Неопределенное поведение - оно такое неопределенное...

→ Ссылка
Автор решения: Генс

"\0" устанавливается автоматически при создании строки символов. Вы всё сделали правильно. В memcpy вы копируете длину строки - это равнозначно установлению квадратных скобок при объявлении и инициализации. Равнозначно можно было указать sizeof(). Вот отсутствие того или другого вызвало бы негодование компилятора. Никаких дополнительных действий больше не требуется. В вашем случае он как и был прописан в 8 байте. В случае посимвольного ввода getchar() для сохранения в строку потребовалось бы самостоятельно устанавливать"\0".

→ Ссылка