Проблема заключается в том, что first
является неинициализированным переменная указатель, то есть указатель имеет произвольную значение- он может указывать в любом месте в памяти.
Если вам очень повезло, оно заканчивается тем, что указывает на неиспользуемую выделенную память, поэтому чтение строки в нее происходит.
Если вам повезет, это указывает на невозвращенный адрес, поэтому чтение строки в нее вызывает segfault.
Если вам не повезло, оно указывает на какую-то действительную память, которая содержит что-то еще, поэтому она работает, но перезаписывает другие данные (или код), вызывая таинственные жесткие сбои при сбое, неправильные результаты или дыры безопасности.
Добавление int i = 0;
не меняет ничего, кроме «повторного кидать кости». Вы также можете получить разные результаты, например, изменив флаги компилятора (особенно если включить или отключить функции отладки или оптимизации).
Например, может быть область стек получает выделяется из выглядит следующим образом, когда ваша main
функция вводится:
pointer to return address in the middle of libc
pointer to data segment
0
В первой версии вашего кода, вы ничего не инициализировать, и first
заканчивается наследованием значения указателя на сегмент данных, поэтому сканирование в него работает. Во второй версии i
заканчивается наследованием указателя на сегмент данных (и переписывает его 0
), а first
заканчивает наследование значением 0
, поэтому сканирование в него segfaults.
Если вы заинтересованы в том, что происходит на самом деле, вы можете посмотреть на сборку, порожденного -S
флагом (или эквивалент для компилятора), или вы можете просто printf("%p\n", first)
, а затем посмотреть, что адрес, который вы получите и выяснить, что там отображается.
Но на самом деле, неважно почему не работает. Он не должен работать, и единственным решением является правильная инициализация указателя на что-то действительное (как объясняет ответ ouah, а остальные объясняют).
Вы не должны выделять свой символ * перед тем, как попытаться получить к ним доступ? –
Ваш простой функция делает ** нет ** работа. – meagar
Вы должны * присваивать * переменную значение, прежде чем * использовать * его значение. Вы не делаете этого для 'first' или' last'. –