<?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[Zeiger = 0;]]></title><description><![CDATA[<pre><code class="language-cpp">class Data;

struct Pointer
{
    Data* data;
};

int main(void)
{
    Pointer* P1 = new Pointer;
    P1-&gt;data = new Data(//blablaa);
    P1 = 0;

    return 0;
}
</code></pre>
<p>Wenn jetzt der Zeiger 'P1' in Nichts zeigt, was passiert mit dem Inhalt, auf den er gezeigt hatte?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/304540/zeiger-0</link><generator>RSS for Node</generator><lastBuildDate>Sun, 09 Aug 2026 11:06:20 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/304540.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 08 Jun 2012 15:46:39 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 15:46:39 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">class Data;

struct Pointer
{
    Data* data;
};

int main(void)
{
    Pointer* P1 = new Pointer;
    P1-&gt;data = new Data(//blablaa);
    P1 = 0;

    return 0;
}
</code></pre>
<p>Wenn jetzt der Zeiger 'P1' in Nichts zeigt, was passiert mit dem Inhalt, auf den er gezeigt hatte?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221040</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221040</guid><dc:creator><![CDATA[RussianTux]]></dc:creator><pubDate>Fri, 08 Jun 2012 15:46:39 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 15:50:30 GMT]]></title><description><![CDATA[<p>Der ist noch immer dort wo er vorher war. Nur hast du leider vergessen wo. Er ist also für immer verloren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221042</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221042</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Fri, 08 Jun 2012 15:50:30 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 15:51:09 GMT]]></title><description><![CDATA[<p>Das Objekt bleibt an der Stelle und der Speicher bleibt reserviert. Und freigeben kannst du ihn dann auch nicht mehr.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221043</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221043</guid><dc:creator><![CDATA[Jonas OSDever]]></dc:creator><pubDate>Fri, 08 Jun 2012 15:51:09 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 15:51:37 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>Der ist noch immer dort wo er vorher war. Nur hast du leider vergessen wo. Er ist also für immer verloren.</p>
</blockquote>
<p>Ein Speicherleck entsteht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221044</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221044</guid><dc:creator><![CDATA[RussianTux]]></dc:creator><pubDate>Fri, 08 Jun 2012 15:51:37 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 15:54:33 GMT]]></title><description><![CDATA[<p>RussianTux schrieb:</p>
<blockquote>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>Der ist noch immer dort wo er vorher war. Nur hast du leider vergessen wo. Er ist also für immer verloren.</p>
</blockquote>
<p>Ein Speicherleck entsteht?</p>
</blockquote>
<p>Exakt.<br />
Alles was du mit new anlegst musst du ja mit delete löschen. Und wenn du vergisst wo das Ding ist, dass du angelegt hast - kannst du ja nicht mehr mit delete löschen. Ergo: ja, Speicherleck.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221047</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221047</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Fri, 08 Jun 2012 15:54:33 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 15:57:51 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>RussianTux schrieb:</p>
<blockquote>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>Der ist noch immer dort wo er vorher war. Nur hast du leider vergessen wo. Er ist also für immer verloren.</p>
</blockquote>
<p>Ein Speicherleck entsteht?</p>
</blockquote>
<p>Exakt.<br />
Alles was du mit new anlegst musst du ja mit delete löschen. Und wenn du vergisst wo das Ding ist, dass du angelegt hast - kannst du ja nicht mehr mit delete löschen. Ergo: ja, Speicherleck.</p>
</blockquote>
<pre><code class="language-cpp">class Data; 

struct Pointer 
{ 
    Data* data; 
}; 

int main(void) 
{ 
    Pointer* P1 = new Pointer; 
    P1-&gt;data = new Data(//blablaa);

    delete P1-&gt;data;
    delete P1;

    return 0; 
}
</code></pre>
<p>Wäre dies der richtige Weg um 'data' und 'P1' loszuwerden oder könnte man &quot;delete P1-&gt;data;&quot; überspringen und direkt bei &quot;delete P1;&quot; anfangen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221048</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221048</guid><dc:creator><![CDATA[RussianTux]]></dc:creator><pubDate>Fri, 08 Jun 2012 15:57:51 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 16:06:15 GMT]]></title><description><![CDATA[<p>Ist ein möglicher Weg so wie du es dastehen hast.<br />
Wenn du P1 zuerst löschst und dann nochmal darauf zugreifst, sei es nur um data zu löschen, dann erzeugst du undefiniertes Verhalten.<br />
Es kann gut gehen. Das Programm kann aber auch abstürtzen. Es können in China auch in dem Moment dann 20 Reissäcke umfallen. Der Standard garantiert dir für nichts.</p>
<p>Alternativ könntest du natürlich einen Destruktor in deiner Struktur definieren, der dann data platt macht, denn dann reicht der aufruf von delte P1;</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221055</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221055</guid><dc:creator><![CDATA[Jonas OSDever]]></dc:creator><pubDate>Fri, 08 Jun 2012 16:06:15 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 16:12:30 GMT]]></title><description><![CDATA[<p>RussianTux schrieb:</p>
<blockquote>
<p>Wäre dies der richtige Weg um 'data' und 'P1' loszuwerden oder könnte man &quot;delete P1-&gt;data;&quot; überspringen und direkt bei &quot;delete P1;&quot; anfangen?</p>
</blockquote>
<p>Nein. Der als &quot;richtig&quot; geltende Weg wäre, dass ein Objekt sich selber um seine Ressourcen kümmert (oder besser noch sie an Ressourcenhandlerklassen auslagert) und sie auch insbesondere selber wieder freigibt:<br />
<a href="https://www.google.de/search?&amp;q=RAII" rel="nofollow">Google: RAII</a></p>
<blockquote>
<p>int main(void)<br />
{<br />
Pointer* P1 = new Pointer;</p>
<p>//...</p>
<p>delete P1;<br />
}</p>
</blockquote>
<p>Dies ist totaler Mist. Wenn ein new und ein dazugehöriges delete im gleichen Scope stehen, dann ist dies das gleiche wie ein Objekt mit automatischer Speicherklasse, bloß in schlecht (sowohl Performance als auch Probleme beim unerwartetem Verlassen des Scopes). Kommst du von Java?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221060</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221060</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 08 Jun 2012 16:12:30 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 16:15:36 GMT]]></title><description><![CDATA[<p>Vielleicht will er auch nur den Umgang mit Zeigern üben <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/2221061</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221061</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 08 Jun 2012 16:15:36 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 16:30:20 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Vielleicht will er auch nur den Umgang mit Zeigern üben <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>
</blockquote>
<p>Und das geht nur, indem man fehlerhaften Mist produziert?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221071</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221071</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Fri, 08 Jun 2012 16:30:20 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 16:39:26 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Vielleicht will er auch nur den Umgang mit Zeigern üben <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>
</blockquote>
<p>So ist es, habe das Thema Zeiger nochmals üben müssen weil ich da noch viele Lücken in der Theorie freigelassen habe.</p>
<pre><code class="language-cpp">class Data;

class Pointer
{
private:
    Data* data;
public:

    Pointer(Data new_data)
    {
        data = new Data(new_data);
    }

    ~Pointer()
    {
        if(data != 0)
            delete data;
    }
};

int main(void)
{
    Data d;
    Pointer* P1 = new Pointer(d);

    // &quot;delete P1;&quot; weggelassen da nicht erforderlich

    return 0;
    // objekt wird beim beenden automatisch gelöscht
}
</code></pre>
<p>Möglicher Lösungsweg oder wieder Fehlversuch?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221076</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221076</guid><dc:creator><![CDATA[RussianTux]]></dc:creator><pubDate>Fri, 08 Jun 2012 16:39:26 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 16:44:13 GMT]]></title><description><![CDATA[<p>RussianTux schrieb:</p>
<blockquote>
<pre><code class="language-cpp">if(data != 0)
            delete data;
</code></pre>
</blockquote>
<p><code>delete</code> nimmt gerne Nullzeiger entgegen.</p>
<p>RussianTux schrieb:</p>
<blockquote>
<pre><code class="language-cpp">// &quot;delete P1;&quot; weggelassen da nicht erforderlich

    return 0;
    // objekt wird beim beenden automatisch gelöscht
}
</code></pre>
</blockquote>
<p>Wird es nicht.</p>
<p>Richtig wäre es so:</p>
<pre><code class="language-cpp">class Pointer
{
private:
    std::unique_ptr&lt;Data&gt; data;
public:

    Pointer(Data new_data)
		: data(new Data(new_data))
    {
    }
};

int main(void)
{
    Data d;
    std::unique_ptr&lt;Pointer&gt; P1(new Pointer(d));

    // &quot;delete P1;&quot; weggelassen da nicht erforderlich

    return 0;
    // objekt wird beim beenden automatisch gelöscht
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2221079</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221079</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Fri, 08 Jun 2012 16:44:13 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 16:49:48 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>RussianTux schrieb:</p>
<blockquote>
<pre><code class="language-cpp">if(data != 0)
            delete data;
</code></pre>
</blockquote>
<p><code>delete</code> nimmt gerne Nullzeiger entgegen.</p>
<p>RussianTux schrieb:</p>
<blockquote>
<pre><code class="language-cpp">// &quot;delete P1;&quot; weggelassen da nicht erforderlich

    return 0;
    // objekt wird beim beenden automatisch gelöscht
}
</code></pre>
</blockquote>
<p>Wird es nicht.</p>
</blockquote>
<p>SeppJ schrieb:</p>
<blockquote>
<blockquote>
<p>int main(void)<br />
{<br />
Pointer* P1 = new Pointer;</p>
<p>//...</p>
<p>delete P1;<br />
}</p>
</blockquote>
<p>Dies ist totaler Mist. Wenn ein new und ein dazugehöriges delete im gleichen Scope stehen, dann ist dies das gleiche wie ein Objekt mit automatischer Speicherklasse, bloß in schlecht (sowohl Performance als auch Probleme beim unerwartetem Verlassen des Scopes). Kommst du von Java?</p>
</blockquote>
<p>[quote=&quot;TyRoXx&quot;]</p>
<p>RussianTux schrieb:</p>
<blockquote>
<p>Richtig wäre es so:</p>
<pre><code class="language-cpp">class Pointer
{
private:
    std::unique_ptr&lt;Data&gt; data;
public:
   
    Pointer(Data new_data)
		: data(new Data(new_data))
    {
    }
};

int main(void)
{
    Data d;
    std::unique_ptr&lt;Pointer&gt; P1(new Pointer(d));

    // &quot;delete P1;&quot; weggelassen da nicht erforderlich

    return 0;
    // objekt wird beim beenden automatisch gelöscht
}
</code></pre>
</blockquote>
<p>std::unique_ptr&lt;T&gt; kommt hier nicht infrage, das ist eine Übungsaufgabe dessen Aufwand nicht gleich die Standard-lib beansprucht, es geht darum zu verstehen was genau hier abläuft</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221083</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221083</guid><dc:creator><![CDATA[RussianTux]]></dc:creator><pubDate>Fri, 08 Jun 2012 16:49:48 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 16:54:23 GMT]]></title><description><![CDATA[<p>RussianTux schrieb:</p>
<blockquote>
<p>Möglicher Lösungsweg oder wieder Fehlversuch?</p>
</blockquote>
<p>So ziemlich alles falsch.</p>
<p>Zeile 11: Initialisierungsliste benutzen, dann wird auch bei Fehler sauber abgeräumt.<br />
Zeile 16: Beschwör lieber ein paar Voodoogötter, das bringt mehr.<br />
Klasse Pointer: Regel der großen Drei verletzt.<br />
Zeile 26: Falscher Unsinn.<br />
Zeile 29: Falscher, gefährlicher Unsinn.</p>
<p>Aus deiner Antwort auf TyRoXx entnehme ich, dass du nicht weißt, was automatische Speicherklasse ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221085</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221085</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 08 Jun 2012 16:54:23 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 16:53:55 GMT]]></title><description><![CDATA[<p>RussianTux schrieb:</p>
<blockquote>
<p>std::unique_ptr&lt;T&gt; kommt hier nicht infrage, das ist eine Übungsaufgabe dessen Aufwand nicht gleich die Standard-lib beansprucht, es geht darum zu verstehen was genau hier abläuft</p>
</blockquote>
<p>In C++ läuft das aber genau so ab. <code>delete</code> ist nicht dazu da, direkt verwendet zu werden.<br />
Was ist eigentlich so schwer daran zu verstehen, dass <code>unique_ptr</code> bei seiner Zerstörung <code>delete</code> aufruft?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221086</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221086</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Fri, 08 Jun 2012 16:53:55 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 17:07:49 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>RussianTux schrieb:</p>
<blockquote>
<pre><code class="language-cpp">if(data != 0)
            delete data;
</code></pre>
</blockquote>
<p><code>delete</code> nimmt gerne Nullzeiger entgegen.</p>
</blockquote>
<p>Allerdings ist es sinnlos, etwas zu löschen, das gar nicht da ist. Keine Ahnung warum das immer das Erste ist, was sinnlos kommentiert wird.<br />
Die Abfrage wird dann falsch, wenn data an dieser Stelle gar nicht 0 sein kann/darf.<br />
Ist eine Abfrage nach diesen Kriterien sinnvoll, kann das Weglassen sogar zu einer (geringen) Verschlechterung der Performance führen. Einen Aufruf der Deallaktionsfunktion kann der Compiler nämlich in der Regel selbst dann nicht wegoptimieren, wenn der Compiler weiß, dass der Zeiger 0 sein wird. Umgekehrt ist der Performanceverlust einer zusätzlichen solchen Abfrage im Verhältnis zu den tatsächlichen Kosten der Deallokation in den Fällen, in denen diese durchgeführt werden muss, vernachlässigbar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221093</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221093</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 08 Jun 2012 17:07:49 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 17:12:10 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>RussianTux schrieb:</p>
<blockquote>
<p>Möglicher Lösungsweg oder wieder Fehlversuch?</p>
</blockquote>
<p>So ziemlich alles falsch.</p>
<p>Zeile 11: Initialisierungsliste benutzen, dann wird auch bei Fehler sauber abgeräumt.</p>
</blockquote>
<p>Irgendwas in der Initialisierungsliste zu machen ist hier weder notwendig noch bringt es irgendwas.<br />
Rohe Zeiger bleiben dumm, auch wenn man sie in der Initialisierungsliste initialisiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221096</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221096</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 08 Jun 2012 17:12:10 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 17:17:52 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>RussianTux schrieb:</p>
<blockquote>
<pre><code class="language-cpp">if(data != 0)
            delete data;
</code></pre>
</blockquote>
<p><code>delete</code> nimmt gerne Nullzeiger entgegen.</p>
</blockquote>
<p>Allerdings ist es sinnlos, etwas zu löschen, das gar nicht da ist. Keine Ahnung warum das immer das Erste ist, was sinnlos kommentiert wird.<br />
Die Abfrage wird dann falsch, wenn data an dieser Stelle gar nicht 0 sein kann/darf.<br />
Ist eine Abfrage nach diesen Kriterien sinnvoll, kann das Weglassen sogar zu einer (geringen) Verschlechterung der Performance führen. Einen Aufruf der Deallaktionsfunktion kann der Compiler nämlich in der Regel selbst dann nicht wegoptimieren, wenn der Compiler weiß, dass der Zeiger 0 sein wird. Umgekehrt ist der Performanceverlust einer zusätzlichen solchen Abfrage im Verhältnis zu den tatsächlichen Kosten der Deallokation in den Fällen, in denen diese durchgeführt werden muss, vernachlässigbar.</p>
</blockquote>
<p>Ich wette das ist nicht das was RussianTux sich gedacht hat. RussianTux denkt nämlich bestimmt, dass new den Wert 0 zurück geben würde, wenn ein Fehler auftritt. Was natürlich nicht der Fall ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221099</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221099</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 08 Jun 2012 17:17:52 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 17:19:11 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>SeppJ schrieb:</p>
<blockquote>
<p>RussianTux schrieb:</p>
<blockquote>
<p>Möglicher Lösungsweg oder wieder Fehlversuch?</p>
</blockquote>
<p>So ziemlich alles falsch.</p>
<p>Zeile 11: Initialisierungsliste benutzen, dann wird auch bei Fehler sauber abgeräumt.</p>
</blockquote>
<p>Irgendwas in der Initialisierungsliste zu machen ist hier weder notwendig noch bringt es irgendwas.<br />
Rohe Zeiger bleiben dumm, auch wenn man sie in der Initialisierungsliste initialisiert.</p>
</blockquote>
<p>Wenn new hier eine Exception schmeißt, wird der Destruktor aufgerufen und es kracht, weil der Zeiger irgendeinen undefinierten Wert hat. Wenn eine Initialisierungsliste benutzt würde, dann würde korrekt abgeräumt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221101</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221101</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 08 Jun 2012 17:19:11 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 17:21:39 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>camper schrieb:</p>
<blockquote>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>RussianTux schrieb:</p>
<blockquote>
<pre><code class="language-cpp">if(data != 0)
            delete data;
</code></pre>
</blockquote>
<p><code>delete</code> nimmt gerne Nullzeiger entgegen.</p>
</blockquote>
<p>Allerdings ist es sinnlos, etwas zu löschen, das gar nicht da ist. Keine Ahnung warum das immer das Erste ist, was sinnlos kommentiert wird.<br />
Die Abfrage wird dann falsch, wenn data an dieser Stelle gar nicht 0 sein kann/darf.<br />
Ist eine Abfrage nach diesen Kriterien sinnvoll, kann das Weglassen sogar zu einer (geringen) Verschlechterung der Performance führen. Einen Aufruf der Deallaktionsfunktion kann der Compiler nämlich in der Regel selbst dann nicht wegoptimieren, wenn der Compiler weiß, dass der Zeiger 0 sein wird. Umgekehrt ist der Performanceverlust einer zusätzlichen solchen Abfrage im Verhältnis zu den tatsächlichen Kosten der Deallokation in den Fällen, in denen diese durchgeführt werden muss, vernachlässigbar.</p>
</blockquote>
<p>Ich wette das ist nicht das was RussianTux sich gedacht hat. RussianTux denkt nämlich bestimmt, dass new den Wert 0 zurück geben würde, wenn ein Fehler auftritt. Was natürlich nicht der Fall ist.</p>
</blockquote>
<p>Vermutlich. Nur fällt das eben unter die Kategorie &quot;Zeiger kann gar nicht 0 sein&quot; und damit ist TyrOXx Begründung schlicht falsch.<br />
Ich bin dafür, diese Abfrage zu eleminieren, wo sie sinnlos ist. Ich habe aber etwas gegen die Begründung dieses Vorhabens damit, dass delete auch Nullzeiger nimmt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221102</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221102</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 08 Jun 2012 17:21:39 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 17:27:04 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>hustbaer schrieb:</p>
<blockquote>
<p>SeppJ schrieb:</p>
<blockquote>
<p>RussianTux schrieb:</p>
<blockquote>
<p>Möglicher Lösungsweg oder wieder Fehlversuch?</p>
</blockquote>
<p>So ziemlich alles falsch.</p>
<p>Zeile 11: Initialisierungsliste benutzen, dann wird auch bei Fehler sauber abgeräumt.</p>
</blockquote>
<p>Irgendwas in der Initialisierungsliste zu machen ist hier weder notwendig noch bringt es irgendwas.<br />
Rohe Zeiger bleiben dumm, auch wenn man sie in der Initialisierungsliste initialisiert.</p>
</blockquote>
<p>Wenn new hier eine Exception schmeißt, wird der Destruktor aufgerufen und es kracht, weil der Zeiger irgendeinen undefinierten Wert hat. Wenn eine Initialisierungsliste benutzt würde, dann würde korrekt abgeräumt.</p>
</blockquote>
<p>Nö.<br />
<a href="http://ideone.com/J4OVg" rel="nofollow">Es werden nur vollständig konstruierte Objekte zerstört</a><br />
Und als vollständig konstruiert gilt das Objekt erst, wenn der Konstruktor regulär verlassen wurde (=ohne eine Exception zu werfen).</p>
<p>Deswegen muss man sich ja in C++ auch für jeden Fliegenschiss eigene RAII Helper-Klassen basteln.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221106</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221106</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 08 Jun 2012 17:27:04 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 17:32:13 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Ich bin dafür, diese Abfrage zu eleminieren, wo sie sinnlos ist. Ich habe aber etwas gegen die Begründung dieses Vorhabens damit, dass delete auch Nullzeiger nimmt.</p>
</blockquote>
<p>In den allermeisten Fällen finde ich die Begründung dass delete auch Nullzeiger nimmt vollkommen ausreichend.</p>
<p>Wenn der &quot;Normalfall&quot; der ist, dass gelöscht werden muss, spielt die Performance keine Rolle (wer optimiert schon auf den Fehlerfall?), und man spart sich eine Zeile = übersichtlicher = juchui.</p>
<p>Bzw. auch wenn es ganz regulär vorkommen kann, aber der minimale Performance-Vorteil der &quot;mit if&quot; Variante einfach nicht ins Gewicht fällt: eine Zeile gespart -&gt; juchui.</p>
<p>In Fällen wo es häufig vorkommen kann dass der Zeiger wirklich Null ist, und in denen der Performanceunterschied möglicherweise nicht irrelevant ist kann bzw. sollte man das &quot;if&quot; stehen lassen.</p>
<p>Und nochwas: DER #1 Grund warum Leute das &quot;if&quot; schreiben ist weil sie nicht wissen dass delete auch Nullzeiger nimmt. Daher finde ich den Hinweis darauf immer gerechtfertigt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221109</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221109</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 08 Jun 2012 17:32:13 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 18:17:53 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>camper schrieb:</p>
<blockquote>
<p>Ich bin dafür, diese Abfrage zu eleminieren, wo sie sinnlos ist. Ich habe aber etwas gegen die Begründung dieses Vorhabens damit, dass delete auch Nullzeiger nimmt.</p>
</blockquote>
<p>In den allermeisten Fällen finde ich die Begründung dass delete auch Nullzeiger nimmt vollkommen ausreichend.</p>
<p>Wenn der &quot;Normalfall&quot; der ist, dass gelöscht werden muss, spielt die Performance keine Rolle (wer optimiert schon auf den Fehlerfall?), und man spart sich eine Zeile = übersichtlicher = juchui.</p>
<p>Bzw. auch wenn es ganz regulär vorkommen kann, aber der minimale Performance-Vorteil der &quot;mit if&quot; Variante einfach nicht ins Gewicht fällt: eine Zeile gespart -&gt; juchui.</p>
</blockquote>
<p>Dann ist <em>das</em> der Grund: Übersichtlichkeit und kürzerer Code. Das sollte dann auch so geschrieben werden. Das liegt nämlich - jedenfalls für micht - nicht so eindeutig auf der Hand. So gibt man die schöne Symmetrie zwischen erfolgreicher Allokation und Deallokation auf. Das macht es nicht unbedingt einfacher, die Korrektheit zu überprüfen.</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>In Fällen wo es häufig vorkommen kann dass der Zeiger wirklich Null ist, und in denen der Performanceunterschied möglicherweise nicht irrelevant ist kann bzw. sollte man das &quot;if&quot; stehen lassen.</p>
</blockquote>
<p>Persönlich ist mir das Performance-Argument ziemlich egal, ich habe es nur gebracht, weil sich manche Leute davon überzeugen lassen. In den Fällen wo es relevant werden kann (Smartpointer), weiß man das in der Regel schon.</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Und nochwas: DER #1 Grund warum Leute das &quot;if&quot; schreiben ist weil sie nicht wissen dass delete auch Nullzeiger nimmt. Daher finde ich den Hinweis darauf immer gerechtfertigt.</p>
</blockquote>
<p>Es besteht allerdings immer noch ein Unterschied zwischen DIngen, die man bloß tun <em>kann</em> und solchen, die man tun <em>sollte</em>.</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>RussianTux schrieb:</p>
<blockquote>
<pre><code class="language-cpp">if(data != 0)
            delete data;
</code></pre>
</blockquote>
<p><code>delete</code> nimmt gerne Nullzeiger entgegen.</p>
</blockquote>
<p>Ist für mich eine Aufforderung, das if wegzulassen. Die bloße Möglichkeit, das tun zu können, ist eben kein Grund, es zu tun. Sein-&gt;Sollen = Fehlschluss.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221112</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221112</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 08 Jun 2012 18:17:53 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 19:43:46 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a><br />
Was du schreibst stimmt alles. Was ich aber nicht rauslesen konnte, ist wann du jetzt persönlich empfehlen würdest das &quot;if&quot; zu schreiben und wann nicht. Bzw. wann du es selbst schreibst und wann nicht.</p>
<p>Ich schreibe es nur in Fällen wo es einen relevanten Performance-Unterschied geben könnte.</p>
<p>Und zwar hauptsächlich deswegen, weil es eben redundant ist.</p>
<p>Das &quot;if&quot; kommuniziert für mich &quot;der Pointer könnte NULL sein&quot;. Und das impliziert für mich wiederum &quot;überall wo kein if steht ist er garantiert nicht NULL&quot;. Und das wiederum ist in Projekten an denen mehrere Leute arbeiten einfach nicht wahr. Kurz: es ist irreführend.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221134</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221134</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 08 Jun 2012 19:43:46 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 21:23:09 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a><br />
Was du schreibst stimmt alles. Was ich aber nicht rauslesen konnte, ist wann du jetzt persönlich empfehlen würdest das &quot;if&quot; zu schreiben und wann nicht. Bzw. wann du es selbst schreibst und wann nicht.</p>
</blockquote>
<p>Es ist größtenteils irrelevant, also gebe ich keine Empfehlung. Persönlich würde ich die Abfrage immer dann verwenden, wenn der Zeiger 0 sein könnte, wenn denn<br />
- ich überhaupt soviel programmieren würde, und<br />
- dabei auch noch explizite delete benutzen würde.<br />
In einem Beitrag fürs Forum lasse ich es i.d.R. weg, weil hier der Vorteil der Kürze klar überwiegt.</p>
<p>imo ist hier eine Empfehlung ungefähr genauso sinnlos wie die, bei main ein return zu schreiben (oder es wegzulassen). Der Unterschied wird nie ausreichen, um eine Änderung bestehenden Codes nur aus diesem Grund rechtfertigen zu können.</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Das &quot;if&quot; kommuniziert für mich &quot;der Pointer könnte NULL sein&quot;. Und das impliziert für mich wiederum &quot;überall wo kein if steht ist er garantiert nicht NULL&quot;. Und das wiederum ist in Projekten an denen mehrere Leute arbeiten einfach nicht wahr. Kurz: es ist irreführend.</p>
</blockquote>
<p>Verstehe das Argument nicht. Natürlich kannst du dich auf die Implikation eines bestimmten Stils nicht verlassen, wenn dieser Stil im Projekt nicht praktiziert wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2221164</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221164</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 08 Jun 2012 21:23:09 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger = 0; on Fri, 08 Jun 2012 22:12:19 GMT]]></title><description><![CDATA[<p>Wenn es schon C++03 und keine STL sein soll, dann bau doch einfach einen shared_ptr für Arme.<br />
Zb soetwas wäre doch recht solide:</p>
<pre><code class="language-cpp">template&lt;typename ValueT&gt;
class shared_ptr
{
private:
    struct ptr_storage
    {
        ptr_storage(ValueT* ptr = 0, std::size_t ref_count = 0)
            : ptr(ptr), ref_count(ref_count)
        { }

        ValueT* ptr;
        std::size_t ref_count;
    }* m_storage;

public:
    shared_ptr()
        : m_storage(0)
    { }

    shared_ptr(ValueT* ptr)
        : m_storage(ptr != 0 ? new ptr_storage(ptr, 1) : 0)
    { }

    shared_ptr(shared_ptr const&amp; other)
        : m_storage(other.m_storage)
    {
        if(m_storage)
            ++m_storage-&gt;ref_count;
    }

    ~shared_ptr()
    {
        if(m_storage)
        {
            if(!(--m_storage-&gt;ref_count))
            {
                delete m_storage-&gt;ptr;
                delete m_storage;
            }
        }
    }

    shared_ptr&lt;ValueT&gt;&amp; operator=(shared_ptr&lt;ValueT&gt; other)
    {
        swap(other);
    }

    void swap(shared_ptr&lt;ValueT&gt;&amp; other)
    {
        ptr_storage* helper = other.m_storage;
        other.m_storage = m_storage;
        m_storage = helper;
    }

    ValueT* get()
    {
        return m_storage-&gt;ptr;
    }

    ValueT* operator-&gt;()
    {
        return get();
    }

    ValueT&amp; operator*()
    {
        return *get();
    }  
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2221191</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2221191</guid><dc:creator><![CDATA[Ethon]]></dc:creator><pubDate>Fri, 08 Jun 2012 22:12:19 GMT</pubDate></item></channel></rss>