Выделение памяти malloc - недопонимание

Функция filename_new формирует имя файла с форматом .new в конце названия файла, которое мы передаем программе таким образом ./exe file и эта функция формирует указатель на строку c с выделением памяти под длину названия файла и вот у меня назрел вопрос, почему моя программа работает, если я выделяю память под 4 байта (если я передам имя file программе) и затем добавляю еще символы .newполучается ведь нужно 8 байт выделить? То есть написать

len = strlen(argv[1]) + 4; 

Потому что .new это еще 4 байта

Но моя программа работает и без этого таким образом, почему?

char* filename_new(char **argv)
{
        int len;
        char *c;

        len = strlen(argv[1]); // strlen возвращает 4, ибо я передал имя file
        c = (char *)malloc(len * sizeof(char));
        sprintf(c, "%s.new", argv[1]);
        return c;
}

В итоге получается, что функция возвращает file.new и это правильно, но я просто понять не могу, нужно ли выделять еще +4 байта из-за .new И почему компилятор не возвращает ошибку из-за того что я выделил чуть меньше чем надо, это же ведь неправильно?


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

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

Язык си очень доверяет программисту. И ругается только если совсем-совсем плохо. Поэтому он не будет такое проверять - программист лучше знает. Более того, часто это просто невозможно - если строка вводится в уже процессе работы программы, то как компилятор об этом сообщит? Но он может добавить проверок, если Вы явно об этом попросите. В gcc/clang это -fsanitize=memory. И в процессе выполнения программы Вы узнаете все, что хотите.

Почему же это работает? Очень часто рантайм выделяет немного больше памяти, чем Вы попросили. И нет никаких проблем записать туда. А также возможно Вам просто повезло и там была свободная память, никем не занятая. Но в один день там окажется другая переменная и будет плохо.

→ Ссылка