<?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[Merkmal einer Klasse lässt sich nicht löschen bzw. static return value - memory leak]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich bin wiedermal auf Hilfe angewiesen <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>
<p>Vielleicht ist die Überschrift etwas verwirrend - das Problem ist folgendes. Wie schon mal erwähnt, das gesamte Programm ist eine OpenGL Anwendung mit GLUT und C++ und ich bin relativ neu in all den drei Sachen.<br />
Ich hatte gerade ein riesiges(!) Memory leak (1GB in 20sec), das ich am eindämmen bin. Hat fast geklappt bis auf folgendes:<br />
Ich habe eine Mathe Klasse. diese enthält folgende Methode:</p>
<pre><code class="language-cpp">//mathpg.h
static float* VertexAddition( float* Vertex1, float* Vertex2 );

//mathpg.cpp
float* MathPG::VertexAddition( float* Vertex1, float* Vertex2 ) 
{
	int DimensionOfVertex = 4;
	float* VertSum = new float[DimensionOfVertex];

	for ( int i = 0; i &lt; DimensionOfVertex - 1; i++ )
	{
		VertSum[i] = Vertex1[i] + Vertex2[i];
	}
	VertSum[3] = 1.0f;

	return VertSum;
}
</code></pre>
<p>Diese benutze ich nun bei der Berechnung hier:</p>
<pre><code class="language-cpp">inBall-&gt;SetBallMovement( MathPG::VertexAddition( inBall-&gt;MovementVertex, Gravity ) );
</code></pre>
<p>Hier wird also eine Methode der Klasse Ball aufgerufen, die pro Frame die neue Position des Balls berechnen soll und diesen darstellt.</p>
<pre><code class="language-cpp">void Ball::SetBallMovement( float* inMovement) 
{
	//delete [] MovementVertex;
	for (int i = 0; i &lt; DimensionOfVertecies; i++ )
	{
		MovementVertex[i] = inMovement[i];
	}
	//MovementVertex = inMovement;
//	delete [] inMovement;

	Ball::UpdateBall( );
}
</code></pre>
<p>Mein Annahme ist, dass in der static Methode der Mathe Klasse jedes mal ein neues float Array auf dem Heap erstellt wird und letztendlich dessen Pointer in der SetBallMovement Methode ankommt.<br />
MovementVertex ist eine Eigenschaft der Klasse Ball.<br />
Ich gehe davon aus, dass der MovementVertex schon einen Speicherbereich im Heap belegt und ich nun durch <code>MovementVertex = inMovement;</code> den Pointer zu diesem existierenden reservierten Heapstück verlieren würde und durch den Pointer zu dem in der statischen Methode der Mathe Klasse erstellen Array ersetze. Also wollte ich den alten MovementVertex löschen, damit das Programm nicht leakt. Das geht aber nicht! Ich bekomme eine Fehlermeldung die mich höchstwahrscheinlich darauf hinweisen soll, dass ich den MovementVertex nicht löschen darf.<br />
Also dachte ich mir, versuche ich es mit einem &quot;Hack&quot;, falls ich keine Merkmale eines Objektes löschen darf, während das Objekt existiert oder sowas und kopiere das Array aus der Mathe Klasse in den Heapspeicher der für das eigentliche Merkmal reserviert ist. Wenn ich das tue und danach das Array aus der Mathe Klasse lösche geht das auch nicht! Selber Fehler...</p>
<p>Nun weiß ich nicht, wo mein Denkfehler ist?!<br />
Hat jemand eine Idee?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/226853/merkmal-einer-klasse-lässt-sich-nicht-löschen-bzw-static-return-value-memory-leak</link><generator>RSS for Node</generator><lastBuildDate>Wed, 30 Sep 2026 10:07:30 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/226853.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 06 Nov 2008 17:09:06 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Merkmal einer Klasse lässt sich nicht löschen bzw. static return value - memory leak on Thu, 06 Nov 2008 17:09:06 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich bin wiedermal auf Hilfe angewiesen <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>
<p>Vielleicht ist die Überschrift etwas verwirrend - das Problem ist folgendes. Wie schon mal erwähnt, das gesamte Programm ist eine OpenGL Anwendung mit GLUT und C++ und ich bin relativ neu in all den drei Sachen.<br />
Ich hatte gerade ein riesiges(!) Memory leak (1GB in 20sec), das ich am eindämmen bin. Hat fast geklappt bis auf folgendes:<br />
Ich habe eine Mathe Klasse. diese enthält folgende Methode:</p>
<pre><code class="language-cpp">//mathpg.h
static float* VertexAddition( float* Vertex1, float* Vertex2 );

//mathpg.cpp
float* MathPG::VertexAddition( float* Vertex1, float* Vertex2 ) 
{
	int DimensionOfVertex = 4;
	float* VertSum = new float[DimensionOfVertex];

	for ( int i = 0; i &lt; DimensionOfVertex - 1; i++ )
	{
		VertSum[i] = Vertex1[i] + Vertex2[i];
	}
	VertSum[3] = 1.0f;

	return VertSum;
}
</code></pre>
<p>Diese benutze ich nun bei der Berechnung hier:</p>
<pre><code class="language-cpp">inBall-&gt;SetBallMovement( MathPG::VertexAddition( inBall-&gt;MovementVertex, Gravity ) );
</code></pre>
<p>Hier wird also eine Methode der Klasse Ball aufgerufen, die pro Frame die neue Position des Balls berechnen soll und diesen darstellt.</p>
<pre><code class="language-cpp">void Ball::SetBallMovement( float* inMovement) 
{
	//delete [] MovementVertex;
	for (int i = 0; i &lt; DimensionOfVertecies; i++ )
	{
		MovementVertex[i] = inMovement[i];
	}
	//MovementVertex = inMovement;
//	delete [] inMovement;

	Ball::UpdateBall( );
}
</code></pre>
<p>Mein Annahme ist, dass in der static Methode der Mathe Klasse jedes mal ein neues float Array auf dem Heap erstellt wird und letztendlich dessen Pointer in der SetBallMovement Methode ankommt.<br />
MovementVertex ist eine Eigenschaft der Klasse Ball.<br />
Ich gehe davon aus, dass der MovementVertex schon einen Speicherbereich im Heap belegt und ich nun durch <code>MovementVertex = inMovement;</code> den Pointer zu diesem existierenden reservierten Heapstück verlieren würde und durch den Pointer zu dem in der statischen Methode der Mathe Klasse erstellen Array ersetze. Also wollte ich den alten MovementVertex löschen, damit das Programm nicht leakt. Das geht aber nicht! Ich bekomme eine Fehlermeldung die mich höchstwahrscheinlich darauf hinweisen soll, dass ich den MovementVertex nicht löschen darf.<br />
Also dachte ich mir, versuche ich es mit einem &quot;Hack&quot;, falls ich keine Merkmale eines Objektes löschen darf, während das Objekt existiert oder sowas und kopiere das Array aus der Mathe Klasse in den Heapspeicher der für das eigentliche Merkmal reserviert ist. Wenn ich das tue und danach das Array aus der Mathe Klasse lösche geht das auch nicht! Selber Fehler...</p>
<p>Nun weiß ich nicht, wo mein Denkfehler ist?!<br />
Hat jemand eine Idee?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1611419</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1611419</guid><dc:creator><![CDATA[Schakai]]></dc:creator><pubDate>Thu, 06 Nov 2008 17:09:06 GMT</pubDate></item><item><title><![CDATA[Reply to Merkmal einer Klasse lässt sich nicht löschen bzw. static return value - memory leak on Thu, 06 Nov 2008 18:30:17 GMT]]></title><description><![CDATA[<p>wirklich sehr, sehr furchtbarer code.<br />
ungetestet:</p>
<pre><code class="language-cpp">#include &lt;vector&gt;

typedef std::vector&lt;float&gt; float_vector;
float_vector MathPG::VertexAddition( const float_vector&amp; Vertex1, const float_vector&amp; Vertex2)
{
    enum { DIMENSIONS = 4 };
    assert(Vertex1.size() == DIMENSIONS &amp;&amp; Vertex2.size() == DIMENSIONS);
    float_vector result(DIMENSIONS);

    for ( int i = 0; i &lt; DIMENSIONS - 1; i++ )
    {
        result[i] = Vertex1[i] + Vertex2[i];
    }
    result[3] = 1.0f;
    return result;
}
</code></pre>
<p>das ist zwar immer noch weit von einer effizienten implementierung entfernt, behebt aber zumindest die gröbsten schnitzer. und leakt nicht.</p>
<p>die dimensionen deines vektors sollten global definiert sein. ich empfehle außerdem eine eigene klasse, die ein paar operatoren implementiert (operator+, operator-).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1611443</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1611443</guid><dc:creator><![CDATA[geschockt]]></dc:creator><pubDate>Thu, 06 Nov 2008 18:30:17 GMT</pubDate></item><item><title><![CDATA[Reply to Merkmal einer Klasse lässt sich nicht löschen bzw. static return value - memory leak on Thu, 06 Nov 2008 21:13:56 GMT]]></title><description><![CDATA[<p>geschockt schrieb:</p>
<blockquote>
<p>wirklich sehr, sehr furchtbarer code.<br />
ungetestet:</p>
<pre><code class="language-cpp">#include &lt;vector&gt;

typedef std::vector&lt;float&gt; float_vector;
float_vector MathPG::VertexAddition( const float_vector&amp; Vertex1, const float_vector&amp; Vertex2)
{
    enum { DIMENSIONS = 4 };
    assert(Vertex1.size() == DIMENSIONS &amp;&amp; Vertex2.size() == DIMENSIONS);
    float_vector result(DIMENSIONS);

    for ( int i = 0; i &lt; DIMENSIONS - 1; i++ )
    {
        result[i] = Vertex1[i] + Vertex2[i];
    }
    result[3] = 1.0f;
    return result;
}
</code></pre>
<p>das ist zwar immer noch weit von einer effizienten implementierung entfernt, behebt aber zumindest die gröbsten schnitzer. und leakt nicht.</p>
<p>die dimensionen deines vektors sollten global definiert sein. ich empfehle außerdem eine eigene klasse, die ein paar operatoren implementiert (operator+, operator-).</p>
</blockquote>
<p>Ok... furchbarer Code also... Naja... Ich habe vor 4 Wochen mit C++ angefangen. Außerdem ist der Code den ich im ersten Post reingestellt habe auf 3 Klassen verteilt. Das eine ist die Mathe Klasse, die Vektoren skaliert, ihre Normalen findet, subtrahiert, addiert usw. Das zweite ist eine Physik Klasse die für Gravitation und Kollisionsdetektion zuständig ist und das dritte ist die Klasse für den Ball.</p>
<p>So - zu deinem Code:</p>
<p><code>typedef std::vector&lt;float&gt; float_vector;</code><br />
- ich habe gelesen, ein <code>vector</code> ist nichts anderes als ein dynamisches Array. Was du da mit den &lt; &gt; Klammern machst kenne ich nicht. Ich nehme an, dass heisst, &quot;ein vector der den Typ float enthält&quot;.</p>
<p><code>float_vector MathPG::VertexAddition( const float_vector&amp; Vertex1, const float_vector&amp; Vertex2)</code><br />
- was bringt mir das <code>const</code> vor den Parametern? Und was bringt es mir anstatt der Pointer eine Referenz zu nehmen? Klar, durch const kann es nicht innerhalb der Funktion geändert werden und der Referenz kann im Gegensatz zum Pointer kein neues Ziel zugewiesen werden. Aber ich weiß es einfach nicht was das in meinem Fall für einen Unterschied macht - also bitte klärt mich auf.</p>
<p><code>enum { DIMENSIONS = 4 };</code><br />
- ist klar!</p>
<p><code>assert(Vertex1.size() == DIMENSIONS &amp;&amp; Vertex2.size() == DIMENSIONS);</code><br />
- hab ich gerade nachgelesen, macht sinn. Aber ich habe bisher nicht die Zeit das Programm Idiotensicher zu schreiben, bin froh wenn es läuft und nicht leakt. Wenn ich vor der Abgabe noch Zeit finde werde ich solche Checks sicher noch einbauen.</p>
<p><code>float_vector result(DIMENSIONS);</code><br />
- Du allokierst den Speicher für den vector auf dem Stack, richtig? Und dadurch willst du das Leak umgehen? Habe ich auch schon versucht. Aber genau das ist ja das Problem. Der vector scheint auf dem Stack wieder gelöscht zu werden, bevor ich ihn brauche. Deshalb schicke ihn in ja auf den Heap mit &quot;new&quot;. Ist das so falsch? Und warum?</p>
<p>Meine Hauptfrage, warum ich keins der Array löschen kann ist damit leider nicht beantwortet. Aber danke dir trotzdem!<br />
Ach und mit Klassen für Operatoren definieren meinst du, dass ich danach vectoren mit + und - addieren bzw. subtrahieren kann?<br />
Das wäre sicher nen cooles feature! Aber da müsste ich mir ja erst anschauen wie ich die Operatoren überlade...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1611516</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1611516</guid><dc:creator><![CDATA[Schakai]]></dc:creator><pubDate>Thu, 06 Nov 2008 21:13:56 GMT</pubDate></item><item><title><![CDATA[Reply to Merkmal einer Klasse lässt sich nicht löschen bzw. static return value - memory leak on Fri, 07 Nov 2008 07:42:08 GMT]]></title><description><![CDATA[<p>Wenn du es unbedingt schnell haben willst (also die Lösung, nicht die Performance) und ohne Leak:</p>
<pre><code class="language-cpp">float *sum = MathPG::VertexAddition( inBall-&gt;MovementVertex, Gravity );
inBall-&gt;SetBallMovement( sum );
delete[] sum;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1611633</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1611633</guid><dc:creator><![CDATA[Fellhuhn]]></dc:creator><pubDate>Fri, 07 Nov 2008 07:42:08 GMT</pubDate></item><item><title><![CDATA[Reply to Merkmal einer Klasse lässt sich nicht löschen bzw. static return value - memory leak on Fri, 07 Nov 2008 07:56:24 GMT]]></title><description><![CDATA[<p>Ersteinmal würde ich dir eher empfehlen dich noch ein wenig länger mit den Grundlagen zu beschäftigen, da die in C++ sehr wichtig sind und du da kaum drum herum kommst.</p>
<p>Aber zu deinem Problem:<br />
Das Problem ist ja, dass du eine Objekt haben willst, dass deinen Vector entspricht. Und du gibst da einen Zeiger auf ein intern erstelltes Objekt zurück, was an sich schon mal schreklich ist, da du somit die Verantwortung an den Aufrufer übergibst, was fatal sein kann, wenn er das nicht weiss.<br />
Ich würde da eher empfehlen eine Klasse Vector zu schreiben, die Kopiersemantik anbietet und du dann intern ein Objekt erstellst und das dann per Kopie nach aussen übergibst. (Schnelle Variante geht da mit std::vector, ist aber ein wenig umständlich, da es nicht einen mathematischen vector entspricht und somit auch keine Operationen dafür anbietet). Ist aber sicher besser, als das per Array zu lösen.</p>
<p>Das mit den &lt;&gt; ist ein template der Standardbibliothek. Nämlich std::vector. Und wie du richtig erkannt hast ergibt das dann einen vector, dass den Typ, den du angibst enthälst.</p>
<blockquote>
<p>float_vector result(DIMENSIONS);<br />
- Du allokierst den Speicher für den vector auf dem Stack, richtig? Und dadurch willst du das Leak umgehen? Habe ich auch schon versucht. Aber genau das ist ja das Problem. Der vector scheint auf dem Stack wieder gelöscht zu werden, bevor ich ihn brauche. Deshalb schicke ihn in ja auf den Heap mit &quot;new&quot;. Ist das so falsch? Und warum?</p>
</blockquote>
<p>Richtig. In deinem Fall passiert das. Aber nur deshalb, weil ein Array keine Kopiersemantik anbietet und somit lediglich ein Zeiger zurückgibst und der Speicher am Ende der Funktion wieder freigegeben wird. geschockt benutzt aber einen std::vector, der sozusagen ein handliches Array ist und welcher auch das Kopieren erlaubt.</p>
<blockquote>
<p>Meine Hauptfrage, warum ich keins der Array löschen kann ist damit leider nicht beantwortet.</p>
</blockquote>
<p>Ich verstehe nicht ganz, was du damit meinst..</p>
<pre><code class="language-cpp">int var[5]; //Array von 5 ints. Du musst dich da nicht drum kümmern, wann es freizugeben ist. Das wird automatisch am Ende des Scopes gemacht. (Sprich, wenn das nächste } kommt (normalerweise Ende einer Funktion)

int* pVar = new int[5]; //du erzeugst ein Array von 5 ints dynamisch und lässt pVar auf den Anfang zeigen.

// delete[] pVar; // So wäre das richtig
pVar = 0; // upps du hast den Zeiger verloren und kannst den Speicher somit nicht mehr freigeben..
</code></pre>
<p>In etwa das?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1611637</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1611637</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Fri, 07 Nov 2008 07:56:24 GMT</pubDate></item><item><title><![CDATA[Reply to Merkmal einer Klasse lässt sich nicht löschen bzw. static return value - memory leak on Fri, 07 Nov 2008 20:41:58 GMT]]></title><description><![CDATA[<p>Hallo!</p>
<p>Erstmal herzlichen Dank für die Antworten!!!</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/17700">@Fellhuhn</a>: Deinen Vorschlag habe ich schon umgesetzt. Danke dir.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18422">@drakon</a>: Welche Art von Grundlagen denkst du sollte ich denn WIE vertiefen? Mir ist das auch schon aufgefallen, dass C++ deutlich &quot;anspruchsvoller&quot; als z.B.: C# ist, womit ich vorher gearbeitet habe.<br />
Liegt ja schon am nicht vorhandenen Heap-Garbage-Collector. Die &quot;was sollte man über C++ wissen&quot; Seite dieses Forums habe ich schon gelesen.<br />
Das mit &lt;&gt; und den Templates habe ich inzwischen schon gelesen. Aber danke!</p>
<p>Zu der eigenen Klasse:<br />
Sagen wir, ich erstelle eine Klasse, die meinen Vektor als float Array enthält und eben die Kopierfunktion bietet. Wenn ich in der Mathe Klasse nun einen Objekt dieser Klasse instanziere, und das dann per Kopiermethode zurückgebe, wird dann das in der Mathe Klasse erstellte Objekt automatisch nach eine der Mathe Additionsmethode gelöscht? Oder muss das in der Kopierfunktion stattfinden? Könntest du ganz eventuell mal kurz die Kopier Methode umreissen?</p>
<p>Ansonsten habe ich nun das Problem, dass Fellhuhn's Weg zwar in dem Fall funktioniert, aber in meinem zweiten Fall in dieser Methode der Klasse Ball (siehe unten) komischer weise nicht (darum ist das delete auskommentiert). Wenn ich das delete [] dort ausführe bekomme ich &quot;Debug Assertion Failed&quot; &quot;Block-Type-is-Valid&quot;. Hab ich mal bei Google nachgeschlagen, liegt normalerweise daran, dass ich etwas lösche das schon gelöscht ist?!<br />
Habt ihr eine Ahnung warum es geht, wenn es sich nicht um eine Eigenschaft eines Ohjektes handelt, aber im anderen Fall diesen Fehler ausgibt?</p>
<pre><code class="language-cpp">void Ball::UpdateBall( void )
{
        float* sum = MathPG::VertexAdditionStack( Position, MovementVertex );	

	for (int i = 0; i &lt; 4; i++ )
	{
		Position[i] = sum[i];
	}
	Ball::DrawBall( );
	//delete [] sum;    //gibt
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1611972</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1611972</guid><dc:creator><![CDATA[Schakai]]></dc:creator><pubDate>Fri, 07 Nov 2008 20:41:58 GMT</pubDate></item><item><title><![CDATA[Reply to Merkmal einer Klasse lässt sich nicht löschen bzw. static return value - memory leak on Sat, 08 Nov 2008 01:21:04 GMT]]></title><description><![CDATA[<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18422">@drakon</a>: Welche Art von Grundlagen denkst du sollte ich denn WIE vertiefen? Mir ist das auch schon aufgefallen, dass C++ deutlich &quot;anspruchsvoller&quot; als z.B.: C# ist, womit ich vorher gearbeitet habe.<br />
Liegt ja schon am nicht vorhandenen Heap-Garbage-Collector. Die &quot;was sollte man über C++ wissen&quot; Seite dieses Forums habe ich schon gelesen.<br />
Das mit &lt;&gt; und den Templates habe ich inzwischen schon gelesen. Aber danke!</p>
<p>Zu der eigenen Klasse:<br />
Sagen wir, ich erstelle eine Klasse, die meinen Vektor als float Array enthält und eben die Kopierfunktion bietet. Wenn ich in der Mathe Klasse nun einen Objekt dieser Klasse instanziere, und das dann per Kopiermethode zurückgebe, wird dann das in der Mathe Klasse erstellte Objekt automatisch nach eine der Mathe Additionsmethode gelöscht? Oder muss das in der Kopierfunktion stattfinden? Könntest du ganz eventuell mal kurz die Kopier Methode umreissen?</p>
</blockquote>
<p>Naja. Allgemein halt. Den Umgang ein wenig mit der Sprache. Aber das kommt eigentlich mit der Zeit.</p>
<p>Ich persönlich würde da ganz einfach eine Klasse machen, die 4 floats enthält (kein Array) und dann fällt die Kopierarbeit auch gleich weg, weil das richtig kopiert wird.</p>
<pre><code class="language-cpp">class Vector
{
 // c'tor
 float x;
 float y;
 float z;
 float a;
 .. //Operatoren Überladung usw.
};
</code></pre>
<pre><code class="language-cpp">Vector a;
// mach aus a was spezielles
Vector b = a; // x,y,z,a wird kopiert.
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1612011</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1612011</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sat, 08 Nov 2008 01:21:04 GMT</pubDate></item></channel></rss>