<?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[(Anfängerfragen&#x2F;Umstieg von C# zu C++) Schlüsselworte new und delete &#x2F; SafeRelease Template]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>da ich beruflich bislang nur im .NET-Umfeld in C# entwickelt habe und nun privat gerne etwas C++ lernen möchte habe ich ein paar Anfängerfragen zu C++.</p>
<p>Derzeit stolpere ich dabei insbesondere über die Erstellung und Freigabe von Objekten. Vielleicht mag mir das jemand von euch leicht verständlich erklären:</p>
<ol>
<li>Worin liegt in C++ der Unterschied ob ich eine Klasseninstanz mit dem Schlüsselwort &quot;new&quot; erzeuge oder ohne?</li>
</ol>
<p>Beispiel:</p>
<p>MyObj CMyObj;</p>
<p>vs.:</p>
<p>MyObj = new CMyObj();</p>
<p>Wann wende ich welche Vorgehensweise an?</p>
<ol start="2">
<li>Worin liegt in C++ der Unterschied ob ich delete oder das SafeRelease-Template (welches in einem MSDN-Beispiel zu Direct2D gefunden habe) zur Freigabe von Objektinstanzen verwende?</li>
</ol>
<p>Beispiel:</p>
<p>delete myObj;</p>
<p>vs.:</p>
<p>SafeRelease(myObj);</p>
<pre><code>template &lt;class T&gt; void SafeRelease(T **ppT)
{
    if (*ppT)
    {
        (*ppT)-&gt;Release();
        *ppT = NULL;
    }
}
</code></pre>
<p>3. Warum wird in dieser konkreten Beispielmethode (die ich in einem Open-Source Projekt gefunden habe) &quot;string&quot; mittels delete[] freigegeben, list und count werden aber nicht freigegeben (ich vermute bei dem Integer-Typen das der Compiler erkennt das der Scope der Methode verlassen wird, aber warum ist dies bei &quot;string&quot; nicht so und bei &quot;list&quot; doch wieder)?</p>
<pre><code>void DebugPrint(char *format, ...)
{
	int     count;
	va_list list;
	char*   string;
	va_start(list, format);
	count = _vscprintf(format, list);
	string = new char[count + 1];
	vsprintf_s(string,count+1,format,list);
	va_end(list);
	OutputDebugStringA(string);
	delete[] string;
}
</code></pre>
<p>Vielen Dank für alle Antworten im voraus,<br />
Matze</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/313522/anfängerfragen-umstieg-von-c-zu-c-schlüsselworte-new-und-delete-saferelease-template</link><generator>RSS for Node</generator><lastBuildDate>Sun, 02 Aug 2026 03:55:11 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/313522.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 03 Feb 2013 00:55:49 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to (Anfängerfragen&#x2F;Umstieg von C# zu C++) Schlüsselworte new und delete &#x2F; SafeRelease Template on Sun, 03 Feb 2013 01:00:07 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>da ich beruflich bislang nur im .NET-Umfeld in C# entwickelt habe und nun privat gerne etwas C++ lernen möchte habe ich ein paar Anfängerfragen zu C++.</p>
<p>Derzeit stolpere ich dabei insbesondere über die Erstellung und Freigabe von Objekten. Vielleicht mag mir das jemand von euch leicht verständlich erklären:</p>
<ol>
<li>Worin liegt in C++ der Unterschied ob ich eine Klasseninstanz mit dem Schlüsselwort &quot;new&quot; erzeuge oder ohne?</li>
</ol>
<p>Beispiel:</p>
<p>MyObj CMyObj;</p>
<p>vs.:</p>
<p>MyObj = new CMyObj();</p>
<p>Wann wende ich welche Vorgehensweise an?</p>
<ol start="2">
<li>Worin liegt in C++ der Unterschied ob ich delete oder das SafeRelease-Template (welches in einem MSDN-Beispiel zu Direct2D gefunden habe) zur Freigabe von Objektinstanzen verwende?</li>
</ol>
<p>Beispiel:</p>
<p>delete myObj;</p>
<p>vs.:</p>
<p>SafeRelease(myObj);</p>
<pre><code>template &lt;class T&gt; void SafeRelease(T **ppT)
{
    if (*ppT)
    {
        (*ppT)-&gt;Release();
        *ppT = NULL;
    }
}
</code></pre>
<p>3. Warum wird in dieser konkreten Beispielmethode (die ich in einem Open-Source Projekt gefunden habe) &quot;string&quot; mittels delete[] freigegeben, list und count werden aber nicht freigegeben (ich vermute bei dem Integer-Typen das der Compiler erkennt das der Scope der Methode verlassen wird, aber warum ist dies bei &quot;string&quot; nicht so und bei &quot;list&quot; doch wieder)?</p>
<pre><code>void DebugPrint(char *format, ...)
{
	int     count;
	va_list list;
	char*   string;
	va_start(list, format);
	count = _vscprintf(format, list);
	string = new char[count + 1];
	vsprintf_s(string,count+1,format,list);
	va_end(list);
	OutputDebugStringA(string);
	delete[] string;
}
</code></pre>
<p>Vielen Dank für alle Antworten im voraus,<br />
Matze</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2295702</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2295702</guid><dc:creator><![CDATA[Matze1974]]></dc:creator><pubDate>Sun, 03 Feb 2013 01:00:07 GMT</pubDate></item><item><title><![CDATA[Reply to (Anfängerfragen&#x2F;Umstieg von C# zu C++) Schlüsselworte new und delete &#x2F; SafeRelease Template on Sun, 03 Feb 2013 03:25:00 GMT]]></title><description><![CDATA[<blockquote>
<ol>
<li>Worin liegt in C++ der Unterschied ob ich eine Klasseninstanz mit dem Schlüsselwort &quot;new&quot; erzeuge oder ohne?</li>
</ol>
</blockquote>
<p>Durch &quot;new&quot; erzeugte Instanzen werden auf dem Heap angelegt und bleiben solange bestehen, bis sie mit delete gelöscht werden. Ohne &quot;new&quot; erzeugte Instanzen bleiben nur bis zum Ende des Gültigkeitsbereiches bestehen und werden dann automatisch zerstört.</p>
<blockquote>
<ol start="2">
<li>Worin liegt in C++ der Unterschied ob ich delete oder das SafeRelease-Template (welches in einem MSDN-Beispiel zu Direct2D gefunden habe) zur Freigabe von Objektinstanzen verwende?</li>
</ol>
</blockquote>
<p>Wie man sieht, prüft SafeRelease erst, ob der Pointer des Objektes gültig ist, ruft dann die Methode Release auf und setzt den Zeiger auf 0.<br />
Das hat mit Speicherverwaltung jedoch nichts zu tun, und ist vermutlich eine Direct3D Anweisung um Dinge (Texturen?) wieder freizugeben.</p>
<blockquote>
<p>3. Warum wird in dieser konkreten Beispielmethode (die ich in einem Open-Source Projekt gefunden habe) &quot;string&quot; mittels delete[] freigegeben, list und count werden aber nicht freigegeben (ich vermute bei dem Integer-Typen das der Compiler erkennt das der Scope der Methode verlassen wird, aber warum ist dies bei &quot;string&quot; nicht so und bei &quot;list&quot; doch wieder)?</p>
</blockquote>
<p>&quot;string&quot; ist ein Zeichenarray und wurde mit new ( string = new char[count + 1]; ) allokiert und liegt damit auf dem Heap und muss daher manuell via delete wieder freigegeben werden. &quot;list&quot; und &quot;count&quot; liegen auf dem Stack und werden daher, wie du schon richtig vermutet hast, beim Verlassen des Scopes zerstört.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2295712</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2295712</guid><dc:creator><![CDATA[sbx320]]></dc:creator><pubDate>Sun, 03 Feb 2013 03:25:00 GMT</pubDate></item><item><title><![CDATA[Reply to (Anfängerfragen&#x2F;Umstieg von C# zu C++) Schlüsselworte new und delete &#x2F; SafeRelease Template on Sun, 03 Feb 2013 07:58:20 GMT]]></title><description><![CDATA[<p>Matze1974 schrieb:</p>
<blockquote>
<ol>
<li>Worin liegt in C++ der Unterschied ob ich eine Klasseninstanz mit dem Schlüsselwort &quot;new&quot; erzeuge oder ohne?</li>
</ol>
</blockquote>
<p>Wie mein Vorredner schon gesagt hat, werden die Objekte, die du ohne <code>new</code> anlegst auf den Stack* angelegt und beim verlassen des Scopes automatisch zerstoert, waehrend du mit <code>new</code> erstellte, die auf dem Heap* angelegt werden, manuell loeschen musst.<br />
Schau dir einfach folgenden Code an:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

class MyClass //CXxxx ist veraltete MFC-Notation
{
    std::string name;

public:
    MyClass(const std::string&amp; name_) : name(name_) //Initialisierungsliste
    {
        std::cout &lt;&lt; &quot;MyClass \&quot;&quot; &lt;&lt; name &lt;&lt; &quot;\&quot; wurde erzeugt!\n&quot;;
    }

    ~MyClass()
    {
        std::cout &lt;&lt; &quot;MyClass \&quot;&quot; &lt;&lt; name &lt;&lt; &quot;\&quot; wird zerstoert :(\n&quot;;
    }
};

int main()
{
    MyClass obj1(&quot;obj1&quot;);
    MyClass* obj2 = new MyClass(&quot;obj2&quot;);

    delete obj2;
    MyClass* obj3 = new MyClass(&quot;obj3&quot;);
    MyClass* obj4 = new MyClass(&quot;obj4&quot;);

    MyClass* objTmp;
    {
        MyClass obj5(&quot;obj5&quot;);
        MyClass* obj6 = new MyClass(&quot;obj6&quot;);
        objTmp = obj6; //Damit wir es aussserhalb des Scopes noch freigegeben koennen
        MyClass* obj7 = new MyClass(&quot;obj7&quot;); //Upps
    }
    delete objTmp; //delete obj6

    delete obj3;
    //delete obj4; //Upps, vergessen
}
</code></pre>
<pre><code>MyClass &quot;obj1&quot; wurde erzeugt!
MyClass &quot;obj2&quot; wurde erzeugt!
MyClass &quot;obj2&quot; wird zerstoert :(
MyClass &quot;obj3&quot; wurde erzeugt!
MyClass &quot;obj4&quot; wurde erzeugt!
MyClass &quot;obj5&quot; wurde erzeugt!
MyClass &quot;obj6&quot; wurde erzeugt!
MyClass &quot;obj7&quot; wurde erzeugt!
MyClass &quot;obj5&quot; wird zerstoert :(
MyClass &quot;obj6&quot; wird zerstoert :(
MyClass &quot;obj3&quot; wird zerstoert :(
MyClass &quot;obj1&quot; wird zerstoert :(
</code></pre>
<p>Und hier siehst du auch das Dilemma: obj4 und obj7 werden zwar allokiert, aber nie wieder freigegeben. Memory-Leak. Deswegen: Nimm kein <code>new</code> , wenn du nicht musst, und wenn dus tust, dann nimm einen Smart-Pointer. Und fuer dynamische Arrays gibts <code>std::vector</code> .</p>
<p>* Der Standard kennt keinen Stack und Heap. Wie das intern geregelt ist, haengt vom Compi und Betriebssystem ab. IdR macht man das auf heute gaengigen Platformen ueber Stack und Heap.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2295714</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2295714</guid><dc:creator><![CDATA[Jonas OSDever]]></dc:creator><pubDate>Sun, 03 Feb 2013 07:58:20 GMT</pubDate></item><item><title><![CDATA[Reply to (Anfängerfragen&#x2F;Umstieg von C# zu C++) Schlüsselworte new und delete &#x2F; SafeRelease Template on Sun, 03 Feb 2013 08:57:20 GMT]]></title><description><![CDATA[<p>Ergänzend:</p>
<p>Matze1974 schrieb:</p>
<blockquote>
<ol>
<li>Worin liegt in C++ der Unterschied ob ich eine Klasseninstanz mit dem Schlüsselwort &quot;new&quot; erzeuge oder ohne?</li>
</ol>
</blockquote>
<p>Mach dir klar, dass es in C++ drei Speicherbereiche gibt:<br />
- Statischer Speicher<br />
- Automatischer Speicher (aka Stack)<br />
- Freispeicher (aka Heap)</p>
<p>C++ zwingt dir hier keine Indirektion auf. In C# liegen Objekte von Klassentypen immer im Heap und was du in der Hand hältst ist nur eine Referenz, die selbst irgendwo im Speicher liegt, typischerweise auf dem Stack oder in einem anderen Objekt. In C++ kannst du direkt mit Objekten hantieren, ohne Umweg über einen Zeiger oder eine Referenz. Das ist dann so ähnlich wie mit den Typen, die man unter C# &quot;value types&quot; nennt.</p>
<p>Die <em>direkte</em> Verwendung von new/delete ist verpönt, weil man sich dadurch viel zu schnell Speicherlecks und ähnliche Probleme einhandelt. Siehe weiter unten für Alternativen.</p>
<p>Matze1974 schrieb:</p>
<blockquote>
<ol start="2">
<li>Worin liegt in C++ der Unterschied ob ich delete oder das SafeRelease-Template (welches in einem MSDN-Beispiel zu Direct2D gefunden habe) zur Freigabe von Objektinstanzen verwende?</li>
</ol>
</blockquote>
<p>Wie schon gesagt wurde, ist -&gt;Release() irgend eine System- oder Design-spezifische Funktion, wahrscheinlich COM-Kram, hat also mit allgemeiner Speicherverwaltung weniger zu tun. So eine SafeDelete-Funktion ist eigentlich nur ein Anzeichen dafür, dass die Autoren nicht soweit gedacht haben, eine Resource wie die eines COM-Objekts in ein geeignetes Objekt zu verpacken, was sich automatisch darum kümmert. Unter modernen Gesichtspunkten ist SafeDelete für'n Arsch, COM hin oder her.</p>
<p>Matze1974 schrieb:</p>
<blockquote>
<p>3. Warum wird in dieser konkreten Beispielmethode (die ich in einem Open-Source Projekt gefunden habe) &quot;string&quot; mittels delete[] freigegeben, list und count werden aber nicht freigegeben (ich vermute bei dem Integer-Typen das der Compiler erkennt das der Scope der Methode verlassen wird, aber warum ist dies bei &quot;string&quot; nicht so und bei &quot;list&quot; doch wieder)?</p>
<pre><code>void DebugPrint(char *format, ...)
{
	int     count;
	va_list list;
	char*   string;
	va_start(list, format);
	count = _vscprintf(format, list);
	string = new char[count + 1];
	vsprintf_s(string,count+1,format,list);
	va_end(list);
	OutputDebugStringA(string);
	delete[] string;
}
</code></pre>
</blockquote>
<p>Das hat wieder mit den 3 Speicherberechen zu tun. Die Variablen count, list und string liegen im automatischen Speicher. Sie werden also automatisch weggeräumt, wenn die Funktion beendet ist. string ist aber ein Zeiger und das worauf er zeigt hat der Autor mit new angelegt. string zeigt also auf einen im Freispeicher allozierten Bereich. Der Freispeicher ist gerade dazu da, dass man selbst die Kontrolle über die Lebenszeit verschiedener darin lebende Objekte entscheiden kann, also muss man die Dinger auch explizit wieder entfernen. Allerdings würde das Programm im modernen C++ Stil trotzdem ganz anders aussehen:</p>
<pre><code>void DebugPrint(char *format, ...)
{
	int     count;
	va_list list;
	vector&lt;char&gt; string;
	va_start(list, format);
	count = _vscprintf(format, list);
	string.resize(count+1);
	vsprintf_s(&amp;string[0],count+1,format,list);
	va_end(list);
	OutputDebugStringA(&amp;string[0]);
}
</code></pre>
<p>Natürlich ist das mit den Ellipsen (...) auch ne blöde und fehleranfällige Idee und gehört eigentlich nicht in modernes C++ rein. Aber hier ist die Sache mit der Speicherverwaltung schön hinter einem vector versteckt. Der Vektor lebt auch im automatischen Speicher und fühlt sich für die im Freispeicher allozierten Elemente <em>verantwortlich</em>. Das heißt, wenn das vector-Objekt aus dem automatischen Speicher geschmissen wird, räumt <em>er</em> auch selbstständig die Elemente aus dem Freispeicher wieder weg. Sowas nennt sich RAII (resource acquisition is initialization) und ist ein Grundpfeiler von <em>guten</em> C++ Programmen.</p>
<p>Es ist wahrscheinlich keine gute Idee, zu glaube, dass C++ so aussehen sollte, wie es dir die Microsoft C++ Beispiele zeigen. So oft habe ich da persönlich auch nicht reingeguckt, aber das, was ich sah, sah leider grottig aus. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":-("
      alt="😞"
    /> Merk dir, dass wenn du es für nötig hältst delete, new[] oder delete[] zu verwenden, du wahrscheinlich etwas falsch machst. Neben den extremst praktischen Container-Klassen (vector ist eine davon) gibt es auch in C++11 noch sehr praktische &quot;Schlauzeiger&quot; (smart pointer): unique_ptr und shared_ptr, die auch mit dem RAII-Gedanken entworfen worden. Man könnte sicherlich das -&gt;Release() in dem Beispiel, was du dir angeguckt hast, einen unique_ptr übernehmen lassen, so das man sich selbst darum nicht mehr kümmern muss.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2295719</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2295719</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Sun, 03 Feb 2013 08:57:20 GMT</pubDate></item><item><title><![CDATA[Reply to (Anfängerfragen&#x2F;Umstieg von C# zu C++) Schlüsselworte new und delete &#x2F; SafeRelease Template on Mon, 04 Feb 2013 15:17:58 GMT]]></title><description><![CDATA[<p>Vielen Dank für die ausführlichen Antworten, dass hilft mir weiter <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2296008</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2296008</guid><dc:creator><![CDATA[Matze1974]]></dc:creator><pubDate>Mon, 04 Feb 2013 15:17:58 GMT</pubDate></item></channel></rss>