fgets в fputs выдает ошибку сегментации

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