#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
на самом деле он неинициализирован, т. Е. не указывает ни на какую допустимую ячейку памяти. Таким образом, программа вызывает неопределенное поведение, и результат не может быть оправдан каким-либо образом.
Во втором коде присутствует та же проблема, поэтому поведение снова не определено.