<?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=149416&amp;view=findpost&amp;p=3802772</guid>
        <pubDate>Fri, 05 Jul 2019 10:03:20 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=3802772</link>
        <description><![CDATA[Ирокез: Как раз про утечку памяти рассказывают почти исключительно адепты решётки и ей подобных. Наталкивает на мысль, что именно решётка и необходима, чтоб утечку организовать. Выделение и <strong class='tag-b'>парное</strong> к нему освобождение памяти всегда делается в связке: написал закорючку для выделения, сразу учитываешь в освобождении. Как можно умудриться напороться на утечку? Хотя, я разок справился. Но на указателях, инкапуслированных в самую глубину. На плюсах. Странно было, что я в тот раз клаву с мышью не перепутал. Исправил после первого же теста. Без логов, профайлеров, с наглухо отвалившимся дебагером.]]></description>
        <author>Ирокез</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=2552792</guid>
        <pubDate>Tue, 30 Mar 2010 22:39:02 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=2552792</link>
        <description><![CDATA[Mr.Delphist: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1818514'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>gena_dj &#064; <time class="tag-quote__quoted-time" datetime="2007-12-27T03:28:05+00:00">27.12.07, 03:28</time></span><div class='quote '>Не будет такого, чтобы двум одновременным потокам, вызывающим xAlloc() вернулся один и тот же указатель. Даже в случае многопроцессорности. </div></div><br>
<br>
В случае, если линкуемся с многопоточным рантаймом. Если же слинкуемся с обычным - здравствуй, лотерея.<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='http://forum.sources.ru/index.php?showtopic=406458' target='_blank'>Spam</a>&quot;</span></span>]]></description>
        <author>Mr.Delphist</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1819204</guid>
        <pubDate>Thu, 27 Dec 2007 14:21:24 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1819204</link>
        <description><![CDATA[gena_dj: Сущствует конечно,<br>но на предыдущей странице почему-то фигурирует EnterCriticalSection() и LeaveCriticalSection()<br>Про выделение памяти за пределами Microsoft не могу ничего сказать.]]></description>
        <author>gena_dj</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1819103</guid>
        <pubDate>Thu, 27 Dec 2007 13:08:52 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1819103</link>
        <description><![CDATA[trainer: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1818514'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>gena_dj &#064; <time class="tag-quote__quoted-time" datetime="2007-12-27T03:28:05+00:00">27.12.07, 03:28</time></span><div class='quote '>Все виндовые xAlloc()</div></div>За пределами Microsoft жизни не существует?]]></description>
        <author>trainer</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1818514</guid>
        <pubDate>Thu, 27 Dec 2007 03:28:05 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1818514</link>
        <description><![CDATA[gena_dj: <strong class='tag-b'>trainer</strong>,<br>
это Вы зря.<br>
Все виндовые xAlloc() тщательно тестируются и полностью потокобезопасны. Не будет такого, чтобы двум одновременным потокам, вызывающим xAlloc() вернулся один и тот же указатель. Даже в случае многопроцессорности.]]></description>
        <author>gena_dj</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1817300</guid>
        <pubDate>Wed, 26 Dec 2007 06:49:51 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1817300</link>
        <description><![CDATA[trainer: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1817248'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>gena_dj &#064; <time class="tag-quote__quoted-time" datetime="2007-12-26T05:47:32+00:00">26.12.07, 05:47</time></span><div class='quote '>Пямять запрашивается из кучи процесса.</div></div>Во-первых, иногда между кучей процесса и функциями вроде malloc стоит посредник. Во-вторых, выделение памяти - не атомарная операция. Если уж непотокобезопасна операция простого увеличения переменной вроде:<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">a += 2;</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script>, то гораздо более сложная процедура выделения памяти - тем более. Поэтому если в менеджере памяти не озадачились синхронизацией - придется делать ее ручками.<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1817248'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>gena_dj &#064; <time class="tag-quote__quoted-time" datetime="2007-12-26T05:47:32+00:00">26.12.07, 05:47</time></span><div class='quote '>Это ничего не изменит.</div></div>Это изменит многое. см. выше.]]></description>
        <author>trainer</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1817248</guid>
        <pubDate>Wed, 26 Dec 2007 05:47:32 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1817248</link>
        <description><![CDATA[gena_dj: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1816278'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>trainer &#064; <time class="tag-quote__quoted-time" datetime="2007-12-25T10:15:06+00:00">25.12.07, 10:15</time></span><div class='quote '>один поток запросил блок памяти в процессе обработки запроса от другого потока.<br>
</div></div><br>
Пямять запрашивается из кучи процесса.<br>
Каждый поток имеет только свой персональный стек.<br>
Поэтому такие запросы обработаются корректно.<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1816278'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>trainer &#064; <time class="tag-quote__quoted-time" datetime="2007-12-25T10:15:06+00:00">25.12.07, 10:15</time></span><div class='quote '><br>
Это не говоря про многоядерные/многопроцессорные системы.<br>
</div></div><br>
Это ничего не изменит.]]></description>
        <author>gena_dj</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1816278</guid>
        <pubDate>Tue, 25 Dec 2007 10:15:06 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1816278</link>
        <description><![CDATA[trainer: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1815948'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>gena_dj &#064; <time class="tag-quote__quoted-time" datetime="2007-12-25T05:17:26+00:00">25.12.07, 05:17</time></span><div class='quote '>Зачем нужна синхронизация? Как она влияет на выделение памяти?</div></div>Возможна ситуация, когда один поток запросил блок памяти в процессе обработки запроса от другого потока. Это не говоря про многоядерные/многопроцессорные системы.]]></description>
        <author>trainer</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1815948</guid>
        <pubDate>Tue, 25 Dec 2007 05:17:26 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1815948</link>
        <description><![CDATA[gena_dj: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1812297'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>ElcnU &#064; <time class="tag-quote__quoted-time" datetime="2007-12-21T13:11:00+00:00">21.12.07, 13:11</time></span><div class='quote '>отсутствие синхронизации доступа к общим участкам памяти из различных потоков</div></div><br>
Зачем нужна синхронизация? Как она влияет на выделение памяти? Выделенная память всегда привязана к процессу, а не к потокам.<br>
<br>
Скорее всего в статье имеется в виду следующее. При использовании <strong class='tag-b'>new</strong> после вызова <strong class='tag-b'>_endthread</strong> память, выделенная в потоке, будет освобождена.]]></description>
        <author>gena_dj</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1812297</guid>
        <pubDate>Fri, 21 Dec 2007 13:11:00 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1812297</link>
        <description><![CDATA[ElcnU: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1812013'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>gena_dj &#064; <time class="tag-quote__quoted-time" datetime="2007-12-21T10:52:55+00:00">21.12.07, 10:52</time></span><div class='quote '>Throne,<br>
А что вы имеете в виду под непотокобезовасными функциями? </div></div><br>
это он меня цитировал.<br>
в общих чертах отсутствие синхронизации доступа к общим участкам памяти из различных потоков<br>
<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1812047'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>C06akaDuka &#064; <time class="tag-quote__quoted-time" datetime="2007-12-21T11:16:14+00:00">21.12.07, 11:16</time></span><div class='quote '>откуда инфа ?</div></div><br>
про new была статья, точно не помню откуда, вот оттуда, но насчет этого я уже отписался в 8м посту :yes-sad: <br>
<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1793719'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Throne &#064; <time class="tag-quote__quoted-time" datetime="2007-12-06T19:00:28+00:00">06.12.07, 19:00</time></span><div class='quote '>ээ, что за глупость? во всяком случае в винде нт это сводится к HeapAlloc(), т.е. RtlAllocateHeap, которая активно юзает EnterCriticalSection и LeaveCriticalSection.<br>
А new - сводится к malloc и по сути является тем же самым - только ещё конструкторы всякие вызываются, экземплеры классов инициализируются и т.п., но память через malloc выделяется... </div></div><br>
это точно в crt исходниках от msvc.<br>
а, например, в ucLinux сборке под ADSP-BF537, нет никакой синхронизации, то есть в таких системах необходимо выполнять синхронизацию при выделении памяти, если работают несколько потоков...<br>
ЗЫ: через телнет проблематично отлавливать косяки, особенно если это проблемы с кучей(у ucLinux просто неадекватная реакция на этот счет бывает) :yes: .]]></description>
        <author>ElcnU</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1812047</guid>
        <pubDate>Fri, 21 Dec 2007 11:16:14 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1812047</link>
        <description><![CDATA[C06akaDuka: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1788900'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>ElcnU &#064; <time class="tag-quote__quoted-time" datetime="2007-12-03T18:15:04+00:00">03.12.07, 18:15</time></span><div class='quote '>malloc, насколько мне известно, непотокобезовасна в отличие от new.</div></div><br>
откуда инфа  ? :huh: <br>
какая может быть потокобезопасность, если в стандарте понятия многопоточности просто нет ?]]></description>
        <author>C06akaDuka</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1812013</guid>
        <pubDate>Fri, 21 Dec 2007 10:52:55 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1812013</link>
        <description><![CDATA[gena_dj: <strong class='tag-b'>Throne</strong>,<br>
А что вы имеете в виду под <strong class='tag-b'>непотокобезовасными</strong> функциями?]]></description>
        <author>gena_dj</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1795255</guid>
        <pubDate>Fri, 07 Dec 2007 16:54:39 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1795255</link>
        <description><![CDATA[Qraizer: <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>но память через malloc выделяется... </div></div>Это не обязательно. Стандарт разрешает даже иметь отдельные &quot;свободные памяти&quot; для C-функций и C++-операторов.]]></description>
        <author>Qraizer</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1794283</guid>
        <pubDate>Fri, 07 Dec 2007 08:38:19 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1794283</link>
        <description><![CDATA[ElcnU: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1793719'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Throne &#064; <time class="tag-quote__quoted-time" datetime="2007-12-06T19:00:28+00:00">06.12.07, 19:00</time></span><div class='quote '>&gt; malloc, насколько мне известно, непотокобезовасна в отличие от new. <br>
<br>
ээ, что за глупость? во всяком случае в винде нт это сводится к HeapAlloc(), т.е. RtlAllocateHeap, которая активно юзает EnterCriticalSection и LeaveCriticalSection.<br>
А new - сводится к malloc и по сути является тем же самым - только ещё конструкторы всякие вызываются, экземплеры классов инициализируются и т.п., но память через malloc выделяется... </div></div><br>
верное замечание :yes: . вчера сам копался в crt исходниках, и, по крайней мере, в студийных(vc2005) исходниках так и сделано.<br>
а вот как дела обстоят на других платформах для меня это еще под большим вопросом :unsure: ? да и вообще в стандарте навряд ли сказано чтото о многопоточности...<br>
про new согласен, просто было малость другое убеждение:(<br>
ну по крайней мере не будет лишним синхронизовать такие вещи<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1788185'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Hsilgos &#064; <time class="tag-quote__quoted-time" datetime="2007-12-03T11:40:46+00:00">03.12.07, 11:40</time></span><div class='quote '><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">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( m_Start )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;newStr-&#62;next &nbsp; &nbsp;= m_Start;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;m_Start-&#62;prev &nbsp; = newStr;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div></ol></div></div></div></div></div></div>]]></description>
        <author>ElcnU</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1793719</guid>
        <pubDate>Thu, 06 Dec 2007 19:00:28 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1793719</link>
        <description><![CDATA[Throne: &gt; malloc, насколько мне известно, непотокобезовасна в отличие от new. <br><br>ээ, что за глупость? во всяком случае в винде нт это сводится к HeapAlloc(), т.е. RtlAllocateHeap, которая активно юзает EnterCriticalSection и LeaveCriticalSection.<br>А new - сводится к malloc и по сути является тем же самым - только ещё конструкторы всякие вызываются, экземплеры классов инициализируются и т.п., но память через malloc выделяется...]]></description>
        <author>Throne</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1792902</guid>
        <pubDate>Thu, 06 Dec 2007 11:29:53 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1792902</link>
        <description><![CDATA[Hsilgos: Значит добавляем 2 класса =)<br>
Небольшой шаблон для автоматического &quot;переключения&quot;. В конструкторе вызывает первую функцию, в деструторе - вторую.<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">template &#60;class T&#62;</div><div class="code_line">class CAutoSwitcher</div><div class="code_line">{</div><div class="code_line">protected:</div><div class="code_line">&nbsp;&nbsp; &nbsp;typedef void(T::*ClassMember)(void) ;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ClassMember m_MemStart;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ClassMember m_MemFinish;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;T* m_ptClass;</div><div class="code_line">&nbsp;&nbsp; &nbsp;CAutoSwitcher(){};// no create with default construtor</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;CAutoSwitcher(T* ptClass,void(T::*mem_on)(void),void(T::*mem_off)(void))</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;m_MemStart &nbsp;= mem_on;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;m_MemFinish = mem_off;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;m_ptClass &nbsp; = ptClass;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if(m_ptClass &amp;&amp; m_MemStart )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;( m_ptClass-&#62;*m_MemStart )();</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;virtual ~CAutoSwitcher()</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if(m_ptClass &amp;&amp; m_MemFinish )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;( m_ptClass-&#62;*m_MemFinish )();</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">};</div></ol></div></div></div></div><br>
<br>
Ну и, собственно, сам класс для синхронизации (только Вынь32):<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">class CSync</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;CRITICAL_SECTION m_crSect;</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;CSync()</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Init();</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;~CSync()</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Destroy();</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;void Init();</div><div class="code_line">&nbsp;&nbsp; &nbsp;void Destroy();</div><div class="code_line">&nbsp;&nbsp; &nbsp;void Lock();</div><div class="code_line">&nbsp;&nbsp; &nbsp;void UnLock();</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">void CSync::Init()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;InitializeCriticalSection(&amp;m_crSect);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void CSync::Destroy()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;DeleteCriticalSection(&amp;m_crSect);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void CSync::Lock()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;EnterCriticalSection(&amp;m_crSect);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void CSync::UnLock()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;LeaveCriticalSection(&amp;m_crSect);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">CSync g_Sync;</div><div class="code_line">&nbsp;</div><div class="code_line">#define LOCK_METHOD() CAutoSwitcher&#60;CSync&#62; lck(&amp;g_Sync,&amp;CSync::Lock,CSync::UnLock);</div></ol></div></div></div></div><br>
<br>
В new/delete в самом начале пишем LOCK_METHOD()]]></description>
        <author>Hsilgos</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1792608</guid>
        <pubDate>Thu, 06 Dec 2007 09:23:02 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1792608</link>
        <description><![CDATA[ElcnU: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=149416&view=findpost&p=1790447'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Hsilgos &#064; <time class="tag-quote__quoted-time" datetime="2007-12-04T18:06:07+00:00">04.12.07, 18:06</time></span><div class='quote '>Объект, который будет безопасно выделять память? чёт не догнал немного =) <br>
Тогда нужно всю функцию &quot;add&quot; загнать в критическую секцию...<br>
Синхронизация - моя слабость. Я с многопоточностью хоть и работал, но редко где приходилось синхронизировать =( </div></div><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">static CMemCollect mem;//статик чтоб один хедер могли подключать несколько сишников</div><div class="code_line">static CSync MemLeakSync;</div><div class="code_line">void * operator new( size_t size , const char* lpszFileName, int nLine )</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;MemLeakSync.Lock();</div><div class="code_line">&nbsp;&nbsp; &nbsp;void * ptr = malloc( size );</div><div class="code_line">&nbsp;&nbsp; &nbsp;MemLeakSync.Unlock();</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( !ptr )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return NULL;</div><div class="code_line">&nbsp;</div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp; &nbsp;MemLeakSync.Lock();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;free( ptr );</div><div class="code_line">&nbsp;&nbsp; &nbsp;MemLeakSync.Unlock();</div><div class="code_line">...</div></ol></div></div></div></div><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">#ifdef MEMLEAK_WIN32</div><div class="code_line">&nbsp;&nbsp;#include &#60;windows.h&#62;</div><div class="code_line">#endif</div><div class="code_line">#ifdef MEMLEAK_NIX</div><div class="code_line">&nbsp;&nbsp;#include &#60;pthread.h&#62;</div><div class="code_line">#endif</div><div class="code_line">&nbsp;</div><div class="code_line">class CSync </div><div class="code_line">{</div><div class="code_line">private:</div><div class="code_line">#ifdef MEMLEAK_WIN32</div><div class="code_line">&nbsp;&nbsp;CRITICAL_SECTION m_CS;</div><div class="code_line">#endif</div><div class="code_line">#ifdef MEMLEAK_NIX</div><div class="code_line">&nbsp;&nbsp;pthread_mutex_t m_Mutex;</div><div class="code_line">#endif</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp;CSync()</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp;//в зависимости от продефайненых параметров производится инициализация объекта синхронизации под нужную платформу типа </div><div class="code_line">&nbsp;&nbsp; &nbsp;#ifdef MEMLEAK_WIN32</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;InitializeCriticalSection(&amp;m_CS);</div><div class="code_line">&nbsp;&nbsp; &nbsp;#endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;#ifdef MEMLEAK_NIX</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;pthread_mutex_init(&amp;m_Mutex, NULL); </div><div class="code_line">&nbsp;&nbsp; &nbsp;#endif</div><div class="code_line">... &nbsp; </div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;&nbsp;~CSync()</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp;#ifdef MEMLEAK_WIN32</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;DeleteCriticalSection(&amp;m_CS);</div><div class="code_line">&nbsp;&nbsp; &nbsp;#endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;#ifdef MEMLEAK_NIX</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;pthread_mutex_destroy(&amp;m_Mutex, NULL); </div><div class="code_line">&nbsp;&nbsp; &nbsp;#endif</div><div class="code_line">... &nbsp; </div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;&nbsp;void Lock()</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp;#ifdef MEMLEAK_WIN32</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;EnterCriticalSection(&amp;m_CS);</div><div class="code_line">&nbsp;&nbsp; &nbsp;#endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;#ifdef MEMLEAK_NIX</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;pthread_mutex_lock(&amp;m_Mutex); </div><div class="code_line">&nbsp;&nbsp; &nbsp;#endif &nbsp; &nbsp; </div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;&nbsp;void Unlock()</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp;#ifdef MEMLEAK_WIN32</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;LeaveCriticalSection(&amp;m_CS);</div><div class="code_line">&nbsp;&nbsp; &nbsp;#endif</div><div class="code_line">&nbsp;&nbsp; &nbsp;#ifdef MEMLEAK_NIX</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;pthread_mutex_unlock(&amp;m_Mutex); </div><div class="code_line">&nbsp;&nbsp; &nbsp;#endif &nbsp; &nbsp; </div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">...</div><div class="code_line">}</div></ol></div></div></div></div><br>
соответственно если MEMLEAK_ХХХ не был продефайнен, то класс получиться пустой, для экономии ресурсов в однопоточный приложениях]]></description>
        <author>ElcnU</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1790447</guid>
        <pubDate>Tue, 04 Dec 2007 18:06:07 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1790447</link>
        <description><![CDATA[Hsilgos: <strong class='tag-b'>ElcnU</strong><br>
Объект, который будет безопасно выделять память? чёт не догнал немного =) <br>
Тогда нужно всю функцию &quot;add&quot; загнать в критическую секцию...<br>
Синхронизация - моя слабость. Я с многопоточностью хоть и работал, но редко где приходилось синхронизировать =(]]></description>
        <author>Hsilgos</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1788900</guid>
        <pubDate>Mon, 03 Dec 2007 18:15:04 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1788900</link>
        <description><![CDATA[ElcnU: <strong class='tag-b'>Hsilgos</strong><br>
malloc, насколько мне известно, непотокобезовасна в отличие от new. В многопоточной программе при активном выделении памяти куча скорей всего подпортится.<br>
Предлагаю добавить класс-заглушку, которых будет взависимости от ОС и наличия многопоточности выполнять синхронизацию.<br>
Объекты синхронизации, например, в винде критическая секция, в никсах мютекс (mutex_lock(...),mutex_unlock(...) ,если память не изменяет :unsure: ) или просто быть пустышкой для однопоточных программ.]]></description>
        <author>ElcnU</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1788185</guid>
        <pubDate>Mon, 03 Dec 2007 11:40:46 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1788185</link>
        <description><![CDATA[Hsilgos: Такой же способ для С++.<br>
Он не претендует на всецелосность (ибо в программе на С++ можно выделять память при помощью malloc/calloc ), а так же он, конечно, не отловит объекты, которые создавались в других библиотеках (CreateObject и т.п.).<br>
<br>
Основные идеи:<br>
Нельзя использовать стандартный коллектор (map,list и пр) так как в них самих используются new/delete. Написание своего аллокатора не помогает. (Во всяком случае, у меня не получилось =) )<br>
Поэтому я написал небольшой класс, который добавляет/удаляет структуры с описанием выделенной памяти.<br>
<br>
У меня вся информация показывается, когда срабатывает конструктор этого класса. Так как объект класса - глобальный, он уничтожится автоматически (естественно, при корректном выходе из программы) после выполнения главной функции. А так как он, по идее, должен создаваться первым, то и уничтожаться последним.<br>
Но никто не запрещает самому вызвать mem.PrintLeaks();<br>
<br>
Вывод осуществляется в окно output (в студии &gt;= 6.0.) В остальных компиляторах не тестировал, не знаю, есть ли такая функция и такая возможность. Строка вывода составлена таким образом, чтобы при двойном клике на этой строка компилятор кидал вас в то место, где была выделена память.<br>
<br>
В целях оптимизации, пихаю структуры в список в начало ( ~push_front ). Идея в том, что при удалении должны, по идее, удаляться указатели по принципу FIFO.<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">#ifdef _DEBUG</div><div class="code_line">#include &quot;ваш_файл.h&quot;</div><div class="code_line">#define new DEBUG_NEW</div><div class="code_line">#endif</div></ol></div></div></div></div><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;stdio.h&#62;</div><div class="code_line">struct MemLeak</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;void &nbsp; &nbsp; &nbsp; &nbsp;*ptr;</div><div class="code_line">&nbsp;&nbsp; &nbsp;size_t &nbsp; &nbsp; &nbsp;size;</div><div class="code_line">&nbsp;&nbsp; &nbsp;const char &nbsp;*file;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int &nbsp; &nbsp; &nbsp; &nbsp; line;</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">#define INFO_LEN 300</div><div class="code_line">&nbsp;</div><div class="code_line">class CMemCollect</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;struct Collector</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;MemLeak leak;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Collector * next;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Collector * prev;</div><div class="code_line">&nbsp;&nbsp; &nbsp;};</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Collector *m_Start;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;void PrintStr(char * a_Str)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;OutputDebugStringA( a_Str );</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;void PrintInfo(MemLeak * a_pLeak)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;char strInfo[INFO_LEN];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( a_pLeak-&#62;file )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sprintf(strInfo,&quot;%s(%d) : size = %d\n&quot;,a_pLeak-&#62;file,a_pLeak-&#62;line,a_pLeak-&#62;size);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sprintf(strInfo,&quot;size = %d\n&quot;,a_pLeak-&#62;size);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;PrintStr(strInfo);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Collector * GetLast()</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Collector *iter = m_Start;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( !iter )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return NULL;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;while ( iter-&#62;next )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iter = iter-&#62;next;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return iter;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;CMemCollect()</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;m_Start = NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;~CMemCollect()</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;PrintLeaks();</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;void PrintLeaks()</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Collector *iter = GetLast();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( iter )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PrintStr(&quot;-=MEMORY LEAK DETECTED!=-\n&quot;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;while( iter != NULL )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MemLeak *str = &amp;iter-&#62;leak;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PrintInfo(str);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Collector * prevIter = iter-&#62;prev;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Remove( iter );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iter = prevIter;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;void Add(MemLeak &amp; a_pLeak)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Collector *newStr = (Collector*)malloc(sizeof(Collector));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( !newStr )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memset(newStr,0,sizeof(Collector));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memcpy(&amp;newStr-&#62;leak,&amp;a_pLeak,sizeof(MemLeak));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( m_Start )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;newStr-&#62;next &nbsp; &nbsp;= m_Start;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;m_Start-&#62;prev &nbsp; = newStr;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;m_Start = newStr;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;void Remove(Collector *iter)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( iter-&#62;prev )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iter-&#62;prev-&#62;next = iter-&#62;next;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( iter-&#62;next )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iter-&#62;next-&#62;prev = iter-&#62;prev;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( iter == m_Start )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;m_Start = iter-&#62;next;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;free(iter);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;void Remove(void * ptr)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Collector *iter = m_Start;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;while( iter != NULL )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( iter-&#62;leak.ptr == ptr )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Remove(iter);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iter = iter-&#62;next;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">CMemCollect mem;</div><div class="code_line">&nbsp;</div><div class="code_line">void * operator new( size_t size , const char* lpszFileName, int nLine )</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;void * ptr = malloc( size );</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( !ptr )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return NULL;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;MemLeak leak &nbsp; &nbsp;= {0};</div><div class="code_line">&nbsp;&nbsp; &nbsp;leak.ptr &nbsp; &nbsp; &nbsp; &nbsp;= ptr;</div><div class="code_line">&nbsp;&nbsp; &nbsp;leak.file &nbsp; &nbsp; &nbsp; = lpszFileName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;leak.line &nbsp; &nbsp; &nbsp; = nLine;</div><div class="code_line">&nbsp;&nbsp; &nbsp;leak.size &nbsp; &nbsp; &nbsp; = size;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;mem.Add(leak);</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;return ptr;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void * operator new( size_t size )</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;void * ptr = malloc( size );</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( !ptr )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return NULL;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;MemLeak leak &nbsp; &nbsp;= {0};</div><div class="code_line">&nbsp;&nbsp; &nbsp;leak.size &nbsp; &nbsp; &nbsp; = size;</div><div class="code_line">&nbsp;&nbsp; &nbsp;leak.ptr &nbsp; &nbsp; &nbsp; &nbsp;= ptr;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;mem.Add(leak);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;return ptr;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void operator delete( void * &nbsp;ptr , const char* lpszFileName, int nLine )</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;mem.Remove( ptr );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;free( ptr );</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void operator delete(void * &nbsp;ptr)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;mem.Remove( ptr );</div><div class="code_line">&nbsp;&nbsp; &nbsp;free( ptr );</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">#define DEBUG_NEW new(__FILE__,__LINE__)</div></ol></div></div></div></div>]]></description>
        <author>Hsilgos</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1191439</guid>
        <pubDate>Tue, 25 Jul 2006 15:40:41 +0000</pubDate>
        <title>Утечка памяти в программах на языке Си</title>
        <link>https://forum.sources.ru/index.php?showtopic=149416&amp;view=findpost&amp;p=1191439</link>
        <description><![CDATA[polyglott: Язык Си славится своей сложностью, и &quot;неприкрытостью&quot; указателей. Поэтому нет ничего странного в том, что утечка памяти так и наровит случиться, и программист часто сталкивается с необходимостью обнаружить и устранить её. Утечка памяти происходит когда программа выделяет динамическую память, и забывает её освободить. Таким образом, чем дольше программа работает, тем больше памяти использует. Рано или поздно память закончится, что приведёт к замедлению системы (и, как показывает опыт, к непредсказуемым глюкам в Windows NT). Почему-то считается, что обнаружить утечку очень сложно (ведь на первый взгляд программа работает правильно) а обнаружить в каком месте программы она происходит - ещё сложнее.<br>
<br>
Чтобы сэкономить человеку время и силы (пессимисты утверждают, что для того чтобы отнять у ЭВМ процессорное время и память) были разработаны специальные средства, помогающие найти ошибку: линты, профилеровщики, библиотеки. Линтами (Lint) называют программы, анализирующие исходный код, и находящие в нём места потенциальных ошибок. Не стоит ждать от линтов эффективности. Профилеровщики запускают вашу программу в виртуальной среде, и по окончании смотрят вся ли память освободилась. Библиотеки - подменяют функции менеджера памяти (malloc, calloc, realloc и free) на свои, ведущие подсчет выделяемой памяти.<br>
<br>
Я смотрел одну такую библиотеку под названием dmalloc. Она состоит из сотен (если не тысяч) строчек кода, снабжена файлом документации (HTML) размером более 150 kB, а на сайте (dmalloc.com) приведён длинный перечень операционных систем, в которых эта библиотека работает (Windows среди них нет, зато есть Cygwin).<br>
<br>
Неужели всё так сложно? Я ничего не придумывал, но естественный ход мысли (он был на 100% естественный, потому что тогда я ещё не знал про вышеописанные средства, и принцип их действия) привел меня к следующему решению. Подменить функции менеджера памяти при помощи препроцессора, примерно так:<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">static int memallocated=0;</div><div class="code_line">#ifndef NDEBUG</div><div class="code_line"># &nbsp; define malloc(size) malloc((memallocated+=size, size))</div><div class="code_line">#endif</div></ol></div></div></div></div><br>
<br>
Теперь ниже по коду выделение памяти функцией malloc будет увеличивать значение переменной memallocated (её легко отслеживать в отладчике). А функция free значит должна уменьшать memallocated. Но насколько? Ведь free не передаётся параметр, содержащий количество байт для освобождения. Я решил эту задачу при помощи хранения размера выделенной области памяти в самой области. То есть выделяется не size байт, а size+sizeof(int), в начало записывается размер, и возвращается указатель не на начало области, а на позицию после записанного нами размера, т.е. не p, а p+sizeof(int).<br>
<br>
Таким образом, если в конце программы переменная memallocated содержит не ноль, то мы можем заключить, что в нашей программе утечка памяти. Но где эту утечку искать? Чтобы найти её было легче, я пошёл ещё дальше, и добавил алгоритм, запоминающий на какой строчке кода и в каком файле выделялся каждый блок памяти. Вот что получилось.<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">/* &nbsp;memtraces.h - replaces functions malloc, calloc, realloc and free with another</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ones that count memory being allocated. Also defines macro that allows to</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;get the size of a memory block (memsize).</div><div class="code_line">&nbsp;&nbsp; &nbsp;Date: 2 August 2006</div><div class="code_line">&nbsp;&nbsp; &nbsp;Author: Jeremiah Shaulov</div><div class="code_line">&nbsp;&nbsp; &nbsp;Lisence: GPL</div><div class="code_line">*/</div><div class="code_line">#ifndef MEMTRACES_INCLUDED</div><div class="code_line">#define MEMTRACES_INCLUDED</div><div class="code_line">#include &#60;stdio.h&#62;</div><div class="code_line">#include &#60;stdlib.h&#62;</div><div class="code_line">#include &#60;string.h&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">static int memallocated=0, mempeak=0, memtraces_cnt=0, pmemtemp;</div><div class="code_line">static struct {void *p; int size; int line; char file[20];} *memtraces_var=NULL;</div><div class="code_line">static FILE *memtraces_log=NULL;</div><div class="code_line">&nbsp;</div><div class="code_line">#define memsize(p) ((p)==NULL ? 0 : ((int*)(p))[-1])</div><div class="code_line">&nbsp;</div><div class="code_line">void *realloc2(void *p, int size)</div><div class="code_line">{ &nbsp; int *p2;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (p == NULL) p2 = (int*)malloc((unsigned)(size)+sizeof(int));</div><div class="code_line">&nbsp;&nbsp; &nbsp;else p2 = (int*)realloc((char*)(p)-sizeof(int), (unsigned)(size)+sizeof(int));</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (p2 == NULL)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{ &nbsp; fprintf(stderr, &quot;\nFailed to allocate %u bytes&quot;, (unsigned)(size)+sizeof(int));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;exit(1);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;*p2 = size;</div><div class="code_line">&nbsp;&nbsp; &nbsp;return p2+1;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void free2(void *p)</div><div class="code_line">{ &nbsp; if (p != NULL) free(((int*)p) - 1);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void *memtraces_add(void *p, int size, int line, const char *file)</div><div class="code_line">{ &nbsp; memallocated += size;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (memallocated &#62; mempeak) mempeak = memallocated;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (p == NULL) return p;</div><div class="code_line">&nbsp;&nbsp; &nbsp;memtraces_cnt++;</div><div class="code_line">&nbsp;&nbsp; &nbsp;memtraces_var = realloc(memtraces_var, memtraces_cnt*sizeof(*memtraces_var));</div><div class="code_line">&nbsp;&nbsp; &nbsp;memtraces_var[memtraces_cnt-1].p = p;</div><div class="code_line">&nbsp;&nbsp; &nbsp;memtraces_var[memtraces_cnt-1].size = size;</div><div class="code_line">&nbsp;&nbsp; &nbsp;memtraces_var[memtraces_cnt-1].line = line;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (strlen(file) &#60;= sizeof(memtraces_var-&#62;file)-1)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;strcpy(memtraces_var[memtraces_cnt-1].file, file);</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;strcpy(memtraces_var[memtraces_cnt-1].file, file+strlen(file)+1-sizeof(memtraces_var-&#62;file));</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (memtraces_log != NULL)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fprintf(memtraces_log, &quot;add %p of size %d; %d allocated (line %d, source %s)\n&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p, size, memallocated, line, file);</div><div class="code_line">&nbsp;&nbsp; &nbsp;return p;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void *memtraces_del(void *p, int line, const char *file)</div><div class="code_line">{ &nbsp; int i;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (p == NULL) return p;</div><div class="code_line">&nbsp;&nbsp; &nbsp;memallocated -= memsize(p);</div><div class="code_line">&nbsp;&nbsp; &nbsp;for (i=0; i&#60;memtraces_cnt; i++) if (memtraces_var[i].p == p)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{ &nbsp; memmove(memtraces_var+i, memtraces_var+i+1, (memtraces_cnt-i-1)*sizeof(*memtraces_var));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memtraces_cnt--;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memtraces_var = realloc(memtraces_var, memtraces_cnt*sizeof(*memtraces_var));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (memtraces_log != NULL)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fprintf(memtraces_log, &quot;del %p of size %d; %d allocated (line %d, source %s)\n&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p, memsize(p), memallocated, line, file);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return p;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;fprintf(stderr, &quot;free(%p) - wrong pointer (line %d, source %s)&quot;, p, line, file);</div><div class="code_line">&nbsp;&nbsp; &nbsp;exit(1);</div><div class="code_line">&nbsp;&nbsp; &nbsp;return p;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void memtraces(FILE *fh)</div><div class="code_line">{ &nbsp; int i;</div><div class="code_line">&nbsp;&nbsp; &nbsp;fprintf(fh, &quot;\n\nMEMORY STATUS:\n&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;for (i=0; i&#60;memtraces_cnt; i++)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{ &nbsp; fprintf(fh, &quot;%p of size %d (line %d, source %s)\n&quot;, memtraces_var[i].p,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;memsize(memtraces_var[i].p), memtraces_var[i].line, memtraces_var[i].file);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;fprintf(fh, &quot;Allocated: %d; Peak: %d&quot;, memallocated, mempeak);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">#ifdef NDEBUG</div><div class="code_line"># &nbsp; define realloc(p, size) realloc2(p, size)</div><div class="code_line"># &nbsp; define malloc(size) realloc2(NULL, size)</div><div class="code_line"># &nbsp; define calloc(size) ( pmemtemp=(size), memset(realloc2(NULL, pmemtemp), 0, pmemtemp) )</div><div class="code_line"># &nbsp; define free(p) free2(p)</div><div class="code_line">#else</div><div class="code_line"># &nbsp; define realloc(p, size) ( pmemtemp=(size), memtraces_add(realloc2( \</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memtraces_del(p, __LINE__, __FILE__), pmemtemp), pmemtemp, __LINE__, __FILE__) )</div><div class="code_line"># &nbsp; define malloc(size) ( pmemtemp=(size), memtraces_add(realloc2( \</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;NULL, pmemtemp), pmemtemp, __LINE__, __FILE__) )</div><div class="code_line"># &nbsp; define calloc(size) ( pmemtemp=(size), memset(memtraces_add(realloc2( \</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;NULL, pmemtemp), pmemtemp, __LINE__, __FILE__), 0, pmemtemp) )</div><div class="code_line"># &nbsp; define free(p) free2(memtraces_del(p, __LINE__, __FILE__))</div><div class="code_line">#endif</div><div class="code_line">&nbsp;</div><div class="code_line">#endif</div></ol></div></div></div></div><br>
<br>
Чтобы получить подробный отчёт о состоянии памяти достаточно в начале программы написать #include &quot;memtraces.h&quot;, и в конце вызвать memtraces(stderr).<br>
<br>
Как видите модуль состоит из 99 строчек кода, и основан на чистом ANSI C, поэтому будет работать на любой платформе. Недостаток - отсутствие поддержки многопоточных программ (её вы можете ввести самостоятельно путем добавления критических секций, но получится ОС-зависимо). Я не пробовал, но думаю что в C++ можно поступить аналогичным способом (там можно подменить new и delete даже не прибегая к помощи препроцессора).<br>
<br>
Вот несколько других решений утечки памяти: valgrind (все хвалят; только Линукс), dmalloc, ccmalloc, LeakTracer, YAMD.<br>
<br>
P.S. Отредактировал 2 August 2006. Исправил ошибку.]]></description>
        <author>polyglott</author>
        <category>C/C++ FAQ</category>
      </item>
	
      </channel>
      </rss>
	