#c #segmentation-fault #malloc #fgets #fputs
#c #ошибка сегментации #malloc #fgets #fputs
Вопрос:
Я попробовал следующий код и получил ошибку сегментации-
int size=30;
char *str;
fputs(fgets(str,size,STDIN),STDOUT);
но когда я запускаю это как —
buff=fgets(str,size,STDIN);
fputs(buff,STDOUT);
это работает просто отлично. Более того, первый код выполняется, если я использую malloc для str. Я не могу понять, как это происходит.
Комментарии:
1. Я подозреваю, что для возврата
fgets
используется внутренний буфер (или, может быть, какой-то специфичный для компилятора эффект оптимизации (магия)). В вашем первом случае, хотя у вас нет никакого буфера, посколькуstr
это просто указатель, а не буфер.
Ответ №1:
Ваша проблема заключается здесь:
char *str;
// de-referenece str in ANY way.
У вас есть указатель, который может указывать куда угодно.Это неопределенное поведение для доступа к произвольной памяти подобным образом.
Тот факт, что он работает в одном случае, но не в другом, является чисто случайным, вы должны предоставить надлежащий буфер, например:
char str[100]; // or whatever size you need.
или использование malloc
для динамического выделения памяти, как вы уже обнаружили.
Как только вы попадаете в темный мир неопределенного поведения, все ставки отменяются.
Это может привести к сбою, это может сработать, это может привести к появлению летающих свиней или носовых демонов или к коллапсу вашей локальной области пространства-времени в сингулярность. Итог, не делайте этого 🙂
Комментарии:
1. я понимаю это, но разве
fputs(fgets(str,size,STDIN),STDOUT);
amp; `buff=fgets(str,size,STDIN); fputs(buff,STDOUT); ‘ не одно и то же?2. Да и нет. Оба они имеют неопределенное поведение, но могут иметь разные результаты, в этом весь смысл UB. На самом деле, один и тот же UB-код вполне имеет право делать одно сегодня, а завтра другое. В тот момент, когда вы используете UB, все ставки отменяются, согласно моему последнему абзацу.
3. Где я могу узнать о внутренней работе? Предложения, если таковые имеются. Потому что я не могу многое узнать об этом со страниц руководства. Заранее спасибо