Почему один метод чтения строки в C с использованием указателя char * работает, а другой нет?

#c #pointers #dangling-pointer

#c #указатели #висячий указатель

Вопрос:

Я читаю строку в C с использованием указателей с помощью следующих двух методов, оба абсолютно одинаковые (по крайней мере, мне они кажутся). Единственное отличие заключается в том, что в одном методе я создал специальную функцию для выполнения этой работы.

Метод 1: // Работает, как ожидалось

 #include <stdio.h>

int main()
{
    char *str;
    char delimiter='.';
    int len=0;
    
    scanf("%c",(str len));
    while(*(str len)!=delimiter)
    {   
          len;
        scanf("%c",(str len));
    }
      len;
    *(str len)='';

    printf("%s",str);

    return 0;
}
  

Метод 2: // Не работает, на экране ничего не печатается

 #include <stdio.h>

int readString(char *str,char delimiter)
{
    int len=0;
    
    scanf("%c",(str len));
    while(*(str len)!=delimiter)
    {   
          len;
        scanf("%c",(str len));
    }
      len;
    *(str len)='';

    return len;
}

int main()
{
    char *str;
    
    int len=readString(str,'.');

    printf("%s",str);

    return 0;
}
  

Я совершенно не понимаю, что я делаю неправильно.

Продолжая играть с кодом в методе 2, я заметил, что если я просто объявляю переменную (даже бесполезную) с инициализацией (например int useless=-1; ) между строками char *str; и int len=readString(str,'.'); , код работает нормально.

Это еще больше усилило мою головную боль.

Кто-нибудь может объяснить, что происходит на самом деле?

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

Комментарии:

1. Просто объявите свою строку str в квадратных скобках вот так char str[100] или с любым размером буфера, который вам нравится. Таким образом, вы освобождаете место для хранения вашей строки. Когда вы просто используете указатель, у вас нет памяти, выделенной для вашей строки, и вы можете указать только на ячейку памяти, где хранится ваша строка, с помощью указателя.

Ответ №1:

В первом коде

  scanf("%c",(str len));
  

вы пытаетесь записать (получить доступ) к ячейке памяти, которая является недопустимой. Обратите внимание, что str на самом деле он неинициализирован, т. Е. не указывает ни на какую допустимую ячейку памяти. Таким образом, программа вызывает неопределенное поведение, и результат не может быть оправдан каким-либо образом.

Во втором коде присутствует та же проблема, поэтому поведение снова не определено.