<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Memory Leak]]></title><description><![CDATA[<p>Abend,</p>
<p>ich habe eine Funktion, die bei mir offenbar ein Memory Leak erzeugt. Folgende Klasse:</p>
<pre><code class="language-cpp">struct SoftwareGraphicsConfigs {
   std::vector&lt;Adapter&gt;		adapters;
};

// Adapter ist eine große Struktur mit maps, vectors etc. 

class Dialog {

struct GfxConfigs {
   RS_TYPE	rsType;
   void*	configsData;
};

Dialog::~Dialog() {
   if(mHasConfigs) 
	SAFE_DELETE(mConfigs.configsData)
}

GfxConfigs	mConfigs;
bool	        mHasConfigs;

void Dialog::setGraphicsConfigs(const GfxConfigs&amp; configs) {
	mConfigs.rsType       = RS_GFX2;
	mConfigs.configsData  = new SoftwareGraphicsConfigs(configs);
	mHasConfigs = true;
}
</code></pre>
<p>Wenn ich Dialog::setGraphicsConfigs NICHT aufrufe, gibt es kein Mem Leak. Dh irgendwo da muss das Memory Leak enstehen. Der Dtor von Dialog wird aufgerufen, dh der allokierte Speicher sollte freigegeben werden.</p>
<p>SoftwareGraphicsConfigs ist eine struct mit einem Vektor von Adapter und Adapter ist eine recht große Struktur mit maps, vectors von anderen Strukturen. Allerdings hat keine dieser Strukturen Zeiger!</p>
<p>Dieser Code hier erzeugt ein Mem Leak (er sagt mir nach Programmende, dass noch 8 Bytes allokiert sind):</p>
<pre><code class="language-cpp">Dialog dialog(&quot;Graphics Settings&quot;);
dialog.setGraphicsConfigs(SWconfigs); // Kommentiere ich das aus, gibts kein Leak!
</code></pre>
<p>Wo liegt das Problem? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/topic/288901/memory-leak</link><generator>RSS for Node</generator><lastBuildDate>Wed, 19 Aug 2026 16:11:20 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/288901.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 24 Jun 2011 19:34:34 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Memory Leak on Fri, 24 Jun 2011 19:34:34 GMT]]></title><description><![CDATA[<p>Abend,</p>
<p>ich habe eine Funktion, die bei mir offenbar ein Memory Leak erzeugt. Folgende Klasse:</p>
<pre><code class="language-cpp">struct SoftwareGraphicsConfigs {
   std::vector&lt;Adapter&gt;		adapters;
};

// Adapter ist eine große Struktur mit maps, vectors etc. 

class Dialog {

struct GfxConfigs {
   RS_TYPE	rsType;
   void*	configsData;
};

Dialog::~Dialog() {
   if(mHasConfigs) 
	SAFE_DELETE(mConfigs.configsData)
}

GfxConfigs	mConfigs;
bool	        mHasConfigs;

void Dialog::setGraphicsConfigs(const GfxConfigs&amp; configs) {
	mConfigs.rsType       = RS_GFX2;
	mConfigs.configsData  = new SoftwareGraphicsConfigs(configs);
	mHasConfigs = true;
}
</code></pre>
<p>Wenn ich Dialog::setGraphicsConfigs NICHT aufrufe, gibt es kein Mem Leak. Dh irgendwo da muss das Memory Leak enstehen. Der Dtor von Dialog wird aufgerufen, dh der allokierte Speicher sollte freigegeben werden.</p>
<p>SoftwareGraphicsConfigs ist eine struct mit einem Vektor von Adapter und Adapter ist eine recht große Struktur mit maps, vectors von anderen Strukturen. Allerdings hat keine dieser Strukturen Zeiger!</p>
<p>Dieser Code hier erzeugt ein Mem Leak (er sagt mir nach Programmende, dass noch 8 Bytes allokiert sind):</p>
<pre><code class="language-cpp">Dialog dialog(&quot;Graphics Settings&quot;);
dialog.setGraphicsConfigs(SWconfigs); // Kommentiere ich das aus, gibts kein Leak!
</code></pre>
<p>Wo liegt das Problem? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2083538</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2083538</guid><dc:creator><![CDATA[Leaker]]></dc:creator><pubDate>Fri, 24 Jun 2011 19:34:34 GMT</pubDate></item><item><title><![CDATA[Reply to Memory Leak on Fri, 24 Jun 2011 19:36:09 GMT]]></title><description><![CDATA[<p>Anmerkung: Es sind deutlich mehr als 8 Bytes Memory Leak:/</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2083539</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2083539</guid><dc:creator><![CDATA[Leaker]]></dc:creator><pubDate>Fri, 24 Jun 2011 19:36:09 GMT</pubDate></item><item><title><![CDATA[Reply to Memory Leak on Fri, 24 Jun 2011 19:38:53 GMT]]></title><description><![CDATA[<p>Was genau ist eigentlich SAFE_DELETE?<br />
Ansonsten sieht der void-Zeiger verdächtig aus - da hat der Compiler es ein wenig schwer herauszufinden, wie er das dahinterliegende Objekt tatsächlich zerstören soll.</p>
<p>PS: Auch wenn du es nicht siehst, vector&lt;&gt; und map&lt;&gt; haben intern Zeiger <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2083545</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2083545</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Fri, 24 Jun 2011 19:38:53 GMT</pubDate></item><item><title><![CDATA[Reply to Memory Leak on Fri, 24 Jun 2011 19:54:02 GMT]]></title><description><![CDATA[<p>SAFE_DELETE ist nur ein Makro, das delete aufruft:</p>
<pre><code class="language-cpp">#define SAFE_DELETE(p)       { if(p) { delete (p);     (p) = NULL; } }
</code></pre>
<p>Ich hab mal zum Test im Dtor den void Zeiger explizit auf SoftwareGraphicsConfigs* gecasted und dann delete aufgerufen. Brauchte auch nichts:(</p>
<p>Die Leaks sehen so aus:</p>
<blockquote>
<p>Detected memory leaks!<br />
Dumping objects -&gt;<br />
{973} normal block at 0x022EA368, 8 bytes long.<br />
Data: &lt;0 7 &gt; 30 FC 37 00 00 00 00 00<br />
{972} normal block at 0x022EB6A0, 48 bytes long.<br />
Data: &lt;FarmDef (Pre-Al&gt; 46 61 72 6D 44 65 66 20 20 28 50 72 65 2D 41 6C<br />
{962} normal block at 0x022E7490, 52 bytes long.<br />
Data: &lt; t. t. t. &gt; 90 74 2E 02 90 74 2E 02 90 74 2E 02 CD CD CD CD<br />
{961} normal block at 0x022E6E30, 8 bytes long.<br />
Data: &lt; . &gt; D8 A1 2E 02 00 00 00 00<br />
{960} normal block at 0x022EA228, 24 bytes long.<br />
Data: &lt;( . ( . ( . &gt; 28 A2 2E 02 28 A2 2E 02 28 A2 2E 02 CD CD CD CD<br />
{959} normal block at 0x022E7080, 8 bytes long.</p>
</blockquote>
<p>Das geht dutzende Zeilen so.</p>
<p>Dass Map/Vektor Zeiger intern benutzen ist mir klar. Aber ich habe in all meinen Strukturen nur map/vektor member, KEINE Zeiger auf map/vektor Instanzen im Heap. Dann sollte doch alles aufgeräumt werden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2083552</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2083552</guid><dc:creator><![CDATA[Leaker]]></dc:creator><pubDate>Fri, 24 Jun 2011 19:54:02 GMT</pubDate></item><item><title><![CDATA[Reply to Memory Leak on Fri, 24 Jun 2011 20:00:19 GMT]]></title><description><![CDATA[<p>Leaker schrieb:</p>
<blockquote>
<p>SAFE_DELETE ist nur ein Makro, das delete aufruft:</p>
<pre><code class="language-cpp">#define SAFE_DELETE(p)       { if(p) { delete (p);     (p) = NULL; } }
</code></pre>
</blockquote>
<p>Das Grauen scheint nicht auszurotten sein. Ist mir vor Jahren schon so begegnet... Nicht nur dass <code>SAFE_DELETE</code> komplett sinnlose Anweisungen enthält, sondern das Ganze ist alles andere als &quot;safe&quot;, alleine schon weil es ein Makro ist.</p>
<p>Wieso verwendest du nicht gleich den richtigen Zeiger statt <code>void*</code> ? Und warum kein normales <code>delete</code> ? Forderst du im Konstruktor von <code>SoftwareGraphicsConfigs</code> noch irgendwo (auch indirekt) Speicher an? Ansonsten, versuch mal hier einen Smart-Pointer einzusetzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2083557</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2083557</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 24 Jun 2011 20:00:19 GMT</pubDate></item><item><title><![CDATA[Reply to Memory Leak on Fri, 24 Jun 2011 20:06:36 GMT]]></title><description><![CDATA[<p>Wenn das Leak in setGraphicsConfigs auftritt, kann eigentlich nur die 2. Zeile mit dem new zum Leak führen. Da das aber im Destruktor freigegeben werden müsste, gibt es eigentlich nur 2 Optionen: 1. delete auf void* is UB -&gt; hast du aber schon gecheckt (solltest du aber trotzdem ändern) oder 2. aus irgendeinem Grund wird mHasConfigs vorher auf false geändert.</p>
<p>Das SAFE_DELETE-Makro ist übrigens unnötig. delete auf Nullzeiger ist definiert als effektlos (das if kann man sich sparen) und das NULL-Setzen des Zeigers muss auch nicht sein, der wird ja nachher eh nicht mehr verwendet (im Allgemeinen sollte man auch auf blindes NULL-Setzen von Zeigern nach dem delete verzichten, weil es nur den Fehler nach hinten schiebt - es darf außer in Außnahmefällen nicht sein, dass delete mehrmals auf den gleichen Zeiger aufgerufen wird).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2083558</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2083558</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Fri, 24 Jun 2011 20:06:36 GMT</pubDate></item><item><title><![CDATA[Reply to Memory Leak on Fri, 24 Jun 2011 20:32:22 GMT]]></title><description><![CDATA[<p>Was macht denn der Konstruktor von SoftwareGraphicsConfigs, insbesondere: wo lässt er die übergebenen Daten?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2083580</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2083580</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Fri, 24 Jun 2011 20:32:22 GMT</pubDate></item><item><title><![CDATA[Reply to Memory Leak on Mon, 27 Jun 2011 09:40:23 GMT]]></title><description><![CDATA[<p>Und wie sieht der Kopierkonstruktor und Zuweisungsoperator aus?</p>
<p>Edit: von GfxConfigs</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2084676</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2084676</guid><dc:creator><![CDATA[DocShoe]]></dc:creator><pubDate>Mon, 27 Jun 2011 09:40:23 GMT</pubDate></item><item><title><![CDATA[Reply to Memory Leak on Mon, 27 Jun 2011 13:58:46 GMT]]></title><description><![CDATA[<p>Also, so etwas wie</p>
<pre><code class="language-cpp">void* badidea = new std::string(&quot;very very very bad idea&quot;); 
 delete badidea;
</code></pre>
<p>ist ... *trommel-wirbel* ... eine ganz schlechte Idee. <em>Natürlich</em> entsteht dabei ein Speicherleck, da über das delete mit void*-Zeiger kein einziger Destruktor läuft -- auch nicht string::~string --- wobei das string-Objekt sicherlich irgendwo zusätzlichen Speicher für das Speichern der Zeichenkette angefordert hat. Dieser würde über den Destruktor freigegeben. Merken: Mit void* schmeißt Du sämliche Typinformationen über Bord und bist auf Dich allein gestellt. C++ ist eine &quot;zero overhead abstraction&quot;-Sprache. Auf Deutsch: Es wird kein unnötiger Ballast (wie zB unnötige Laufzeit-Typ-Information) mitgeschleppt. Gerade als Anfänger solltest Du so etwas wie void*-Frickeleien vermeiden.</p>
<p>Zweitens: Wie willst Du überhaupt beurteilen, ob Dein Programm ein Speicherleckt hat? Mach Dir mal ein paar Gedanken dazu, ob die Art und Weise, wie Du das ermittelst, überhaupt korrekt sein kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2084843</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2084843</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Mon, 27 Jun 2011 13:58:46 GMT</pubDate></item><item><title><![CDATA[Reply to Memory Leak on Mon, 27 Jun 2011 15:44:44 GMT]]></title><description><![CDATA[<p>Wenn du setGraphicsConfigs() zweimal hintereinander aufrufst, kannst du dir ein Speicherleck einfangen.</p>
<p>Ansonsten sieht, wie schon krümelkacker sagte, die Frickelei mit void* böse aus. Dein Destruktor löscht zwar configsData, aber er ruft nicht den Destruktor von SoftwareGraphicsConfigs auf. Das struct hat zwar keine von dir definierten Destruktor, aber (vermutlich) einen Standarddestruktor welche automatisch die Member-Destruktoren aufruft.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2084897</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2084897</guid><dc:creator><![CDATA[Bitte ein Bit]]></dc:creator><pubDate>Mon, 27 Jun 2011 15:44:44 GMT</pubDate></item></channel></rss>