<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=428744&amp;view=findpost&amp;p=3871988</guid>
        <pubDate>Wed, 20 Jul 2022 08:18:10 +0000</pubDate>
        <title>Тем, кто задаёт вопросы на Stack Overflow: &amp;quot;Почему код не работает?&amp;quot;</title>
        <link>https://forum.sources.ru/index.php?showtopic=428744&amp;view=findpost&amp;p=3871988</link>
        <description><![CDATA[Unicorn developer: <br>
<strong class='tag-b'>На сайте Stack Overflow много вопросов от людей, ещё только изучающих языки программирования.<br>
Лайфхак: ответы на многие эти вопросы можно получить сразу, запустив анализатор кода. Получится быстрее.</strong><br>
<br>
<img class='tag-img' src='https://import.viva64.com/docx/blog/0959_PVS_education_1_ru/image1.png' alt='user posted image'><br>
<br>
Эту заметку меня побудила написать дискуссия &quot;<a class='tag-url' href='https://stackoverflow.com/questions/72478692/segmentation-fault-when-converting-char-to-char/' target='_blank'>Segmentation fault when converting char * to char **</a>&quot; на сайте Stack Overflow. Человек, изучающий программирование, интересуется, что не так с его кодом.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#include &#60;unistd.h&#62;</div><div class="code_line">#include &#60;stdio.h&#62;</div><div class="code_line">#include &#60;string.h&#62;</div><div class="code_line">#include &#60;fcntl.h&#62;</div><div class="code_line">#include &#60;assert.h&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">char **get_words(char *buffer, char delimiter)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;printf(&quot;buffer = %s\n&quot;, buffer);</div><div class="code_line">&nbsp;&nbsp; &nbsp;char **words = malloc(sizeof(char *) * 100);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (words == NULL) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;printf(&quot;Malloc Error\n&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;exit(84);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;for (int i = 0; i &#60; 100; i++) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;words[i] = malloc(sizeof(char) * 100);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (words[i] == NULL) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printf(&quot;Malloc Error\n&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit(84);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;int word_count = 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int l = 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;for (int i = 0; buffer[i] != &#39;{text}&#39; &amp;&amp; buffer[i] &nbsp;!= &#39;\n&#39;; i++, l++) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (buffer[i] == delimiter) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;words[word_count][l] = &#39;{text}&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;word_count++;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;l = -1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;words[word_count][l] = buffer[i];</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;words[word_count][l] = &#39;{text}&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;return (words);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">int main()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;char *buffer = malloc(sizeof(char) * 100);</div><div class="code_line">&nbsp;&nbsp; &nbsp;buffer = &quot;hello world !\n&quot;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;char **words = get_words(buffer, &#39; &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;printf(&quot;words[0]= %s\n&quot;, words[0]);</div><div class="code_line">&nbsp;&nbsp; &nbsp;free (buffer);</div><div class="code_line">&nbsp;&nbsp; &nbsp;char **reply = get_words(&quot;Second call\n&quot;, &#39; &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;printf(&quot;reply[0] = %s\n&quot;, reply[0]);</div><div class="code_line">}</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
Таких вопросов достаточно на Stack Overflow. И часто на них отвечают медленно и неохотно. Это обоснованно. Согласитесь, не хочется изучать достаточно большой текст программы только ради того, чтобы найти какую-то скучную ошибку. Эти ошибки, как правило, связаны с ещё недостаточным знанием языка, и ответ, скорее всего, сведётся к совету прочитать определённый раздел книги или документации.<br>
<br>
Это не снобизм со стороны более опытных разработчиков. Им просто не очень интересно тратить время на то, чтобы разбираться, что не так с лабораторными работами.<br>
<br>
Вернёмся к вопросу на Stack Overflow, про который я говорил выше. Вопрос висел уже пару дней, а ответа всё нет. Как человеку продвинуться дальше?<br>
<br>
Одним из помощников в обучении программированию может стать статический анализатор. Это программа, которая выполняет <a class='tag-url' href='https://pvs-studio.com/ru/blog/terms/0073/' target='_blank'>code review</a> и сообщает о подозрительных участках кода. Статические анализаторы не заменяют практику обзора кода, выполняемого коллегой, но хорошо дополняют его и позволяют находить многие ошибки на самом раннем этапе.<br>
<br>
<a class='tag-url' href='https://godbolt.org/z/svdEPrW8n' target='_blank'>Запустим</a> online-версию анализатора PVS-Studio для приведённого в вопросе кода. Первым интересным и важным предупреждением является сообщение: <a class='tag-url' href='https://pvs-studio.com/ru/docs/warnings/v1031/' target='_blank'>V1031</a> The &#39;malloc&#39; function is not declared. Passing data to or from this function can be affected.<br>
<br>
Без объявления функции malloc программа уже работает непонятным образом. В языке Си считается, что если функция не объявлена, то она возвращает int. А на самом деле это указатель. Чем это опасно, рассказано в заметке &quot;<a class='tag-url' href='https://pvs-studio.com/ru/blog/posts/cpp/0033/' target='_blank'>Красивая 64-битная ошибка на языке Си</a>&quot;. Исправим эту проблему, добавив #include &lt;stdlib.h&gt;.<br>
<br>
Теперь <a class='tag-url' href='https://godbolt.org/z/ehqsaeMqW' target='_blank'>вывод анализатора</a> изменится, и мы видим следующую серьёзную проблему: 43:1: note: V773 The &#39;buffer&#39; pointer was assigned values twice without releasing the memory. A memory leak is possible.<br>
<br>
Ошибка здесь:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">char *buffer = malloc(sizeof(char) * 100);</div><div class="code_line">buffer = &quot;hello world !\n&quot;;</div><div class="code_line">....</div><div class="code_line">free (buffer);</div></ol></div></div></div></div><br>
Значение указателя перетирается. Чтобы скопировать строку в буфер, нужно использовать специальные функции, например <a class='tag-url' href='https://en.cppreference.com/w/c/string/byte/strcpy' target='_blank'>strcpy</a>. Внесём исправления.<br>
<br>
<a class='tag-url' href='https://godbolt.org/z/Kar998xbv' target='_blank'>Исправленный код</a>:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#include &#60;unistd.h&#62;</div><div class="code_line">#include &#60;stdio.h&#62;</div><div class="code_line">#include &#60;string.h&#62;</div><div class="code_line">#include &#60;fcntl.h&#62;</div><div class="code_line">#include &#60;assert.h&#62;</div><div class="code_line">#include &#60;stdlib.h&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">char **get_words(char *buffer, char delimiter)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;printf(&quot;buffer = %s\n&quot;, buffer);</div><div class="code_line">&nbsp;&nbsp; &nbsp;char **words = malloc(sizeof(char *) * 100);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (words == NULL) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;printf(&quot;Malloc Error\n&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;exit(84);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;for (int i = 0; i &#60; 100; i++) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;words[i] = malloc(sizeof(char) * 100);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (words[i] == NULL) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printf(&quot;Malloc Error\n&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit(84);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;int word_count = 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int l = 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;for (int i = 0; buffer[i] != &#39;{text}&#39; &amp;&amp; buffer[i] &nbsp;!= &#39;\n&#39;; i++, l++) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (buffer[i] == delimiter) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;words[word_count][l] = &#39;{text}&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;word_count++;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;l = -1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;words[word_count][l] = buffer[i];</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;words[word_count][l] = &#39;{text}&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;return (words);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">int main()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;char *buffer = malloc(sizeof(char) * 100);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (buffer == NULL)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;exit(84);</div><div class="code_line">&nbsp;&nbsp; &nbsp;strcpy(buffer, &quot;hello world !\n&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;char **words = get_words(buffer, &#39; &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;printf(&quot;words[0]= %s\n&quot;, words[0]);</div><div class="code_line">&nbsp;&nbsp; &nbsp;free (buffer);</div><div class="code_line">&nbsp;&nbsp; &nbsp;char **reply = get_words(&quot;Second call\n&quot;, &#39; &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;printf(&quot;reply[0] = %s\n&quot;, reply[0]);</div><div class="code_line">}</div></ol></div></div></div></div><br>
Этот код ещё нельзя назвать красивым и безопасным, но он работает. Так что такой способ поиска ошибок вполне может помочь в процессе обучения.<br>
<br>
<strong class='tag-b'>Дополнительные ссылки:</strong><br>
<br>
<a class='tag-url' href='https://pvs-studio.com/ru/blog/terms/0046/' target='_blank'>Статический анализ кода</a>.<br>
PVS-Studio: <a class='tag-url' href='https://pvs-studio.com/ru/pvs-studio/godbolt/' target='_blank'>online версия</a>.<br>
PVS-Studio: <a class='tag-url' href='https://pvs-studio.com/ru/order/for-students/' target='_blank'>бесплатное использование для студентов</a>.<br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray"><span class='tag-size' data-value='7' style='font-size:7pt;'>Это сообщение было перенесено сюда или объединено из темы &quot;Тем, кто задаёт вопросы на Stack Overflow: &quot;Почему код не работает?&quot;&quot;</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray"><span class='tag-size' data-value='7' style='font-size:7pt;'>Эта тема была разделена из темы &quot;<a class='tag-url' href='https://forum.sources.ru/index.php?showtopic=428150' target='_blank'>Челлендж от анализатора PVS-Studio: насколько вы внимательны?</a>&quot;</span></span>]]></description>
        <author>Unicorn developer</author>
        <category>C/C++: Прочее</category>
      </item>
	
      </channel>
      </rss>
	