<?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[Verkettete Liste]]></title><description><![CDATA[<p>Folgenden Code von hier <a href="http://c-plusplus.net/forum/viewtopic-var-p-is-1324660.html#1324660" rel="nofollow">http://c-plusplus.net/forum/viewtopic-var-p-is-1324660.html#1324660</a> check ich irgendwie nicht, und zwar:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

class SList //1
{
public:
    typedef int value_type;

private:
    class Node  // Listenelement 2
    {
    public:
        explicit Node( const value_type&amp; x, Node* next = 0 )
                :m_next( next ), m_value( x )
        {
            cout &lt;&lt; &quot;Node\n&quot;;
        }
        Node* m_next;
        value_type m_value;
    };

public:
    SList()     // ersetzt das init()
        : m_kopf( value_type() )
        , m_ende( &amp;m_kopf )
    {cout &lt;&lt; &quot;SList\n&quot;;}
    ~SList() { clear(); } // immer schön wieder aufräumen

    void push_back( const value_type&amp; x ) // ersetzt das einfuegen() was ein anhaengen() ist
    {
        m_ende-&gt;m_next = new Node( x );
        m_ende = m_ende-&gt;m_next;
    }

    void clear() // ersetzt das ende()
    {
        for( Node* p = m_kopf.m_next; p; )
        {
            Node* tmp = p;
            p = p-&gt;m_next;
            delete tmp;
        }
        m_kopf.m_next = 0;
        m_ende = &amp;m_kopf;
    }

    // --   Ausgabe
    std::ostream&amp; ausgeben( std::ostream&amp; out, const char* delim = &quot;&quot; )
    {
        for( Node* p = m_kopf.m_next; p; p = p-&gt;m_next )
        {
            out &lt;&lt; p-&gt;m_value &lt;&lt; delim;
        }
        return out;
    }

private:
    // Kopieren z.Zt. nicht vorgesehen; -&gt; &quot;Regel der drei&quot;
    SList( const SList&amp; );
    SList&amp; operator=( const SList&amp; );

    // --   Member
    Node m_kopf;
    Node* m_ende;
};

int main()
{
    SList A;
    A.push_back(20);
    A.push_back(200);

    return 0;
}
</code></pre>
<p>Es gibt anfangs ein &quot;m_kopf&quot; Node Objekt, und einen Node Zeiger namens &quot;m_ende&quot;.<br />
&quot;m_kopf&quot; wird mit 0 initialisiert, m_ende zeigt auf m_kopf.</p>
<p>// m_kopf --&gt; a --&gt; b --&gt; c --&gt; d --&gt; m_ende<br />
// ^-----------------------------------------------|</p>
<p>Doch jetzt wenn ich zur Funktion push_back() gehe, dann blick ich nicht mehr durch.</p>
<pre><code class="language-cpp">void push_back( const value_type&amp; x ) // ersetzt das einfuegen() was ein anhaengen() ist
    {
        m_ende-&gt;m_next = new Node( x );
        m_ende = m_ende-&gt;m_next;
    }
</code></pre>
<p>Der Node Zeiger &quot;m_next&quot; aus &quot;m_kopf&quot; hat nun ein neus Node Objekt auf dem HEap erstelle und Zeigt darauf:<br />
m_kopf.m_next --&gt; neues Objekt<br />
Und die Elementvariable &quot;m_next&quot; vom Zeiger &quot;m_next&quot; zeigt auf NULL. (konstruktor)<br />
Dann übernimmt m_ende die Adresse von dem neuen Objekt (m_next).<br />
Trotzdem check ich net was das nun alles bringt. Da soll sich doch so eine Zeigerkettet ergeben....mh ich hab glaub irgendwas nicht richtig verstanden!? Kann mir jemand des alles nochmal n bissel erklären, den irgendwas mach ich ziemlich falsch in meinem Kopf.</p>
<p><a href="http://www.pictureupload.de/originals/pictures/041107125828_mein_gehirn.JPG" rel="nofollow">http://www.pictureupload.de/originals/pictures/041107125828_mein_gehirn.JPG</a></p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/196894/verkettete-liste</link><generator>RSS for Node</generator><lastBuildDate>Thu, 01 Oct 2026 03:24:07 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/196894.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 04 Nov 2007 11:59:11 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Verkettete Liste on Sun, 04 Nov 2007 11:59:11 GMT]]></title><description><![CDATA[<p>Folgenden Code von hier <a href="http://c-plusplus.net/forum/viewtopic-var-p-is-1324660.html#1324660" rel="nofollow">http://c-plusplus.net/forum/viewtopic-var-p-is-1324660.html#1324660</a> check ich irgendwie nicht, und zwar:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

class SList //1
{
public:
    typedef int value_type;

private:
    class Node  // Listenelement 2
    {
    public:
        explicit Node( const value_type&amp; x, Node* next = 0 )
                :m_next( next ), m_value( x )
        {
            cout &lt;&lt; &quot;Node\n&quot;;
        }
        Node* m_next;
        value_type m_value;
    };

public:
    SList()     // ersetzt das init()
        : m_kopf( value_type() )
        , m_ende( &amp;m_kopf )
    {cout &lt;&lt; &quot;SList\n&quot;;}
    ~SList() { clear(); } // immer schön wieder aufräumen

    void push_back( const value_type&amp; x ) // ersetzt das einfuegen() was ein anhaengen() ist
    {
        m_ende-&gt;m_next = new Node( x );
        m_ende = m_ende-&gt;m_next;
    }

    void clear() // ersetzt das ende()
    {
        for( Node* p = m_kopf.m_next; p; )
        {
            Node* tmp = p;
            p = p-&gt;m_next;
            delete tmp;
        }
        m_kopf.m_next = 0;
        m_ende = &amp;m_kopf;
    }

    // --   Ausgabe
    std::ostream&amp; ausgeben( std::ostream&amp; out, const char* delim = &quot;&quot; )
    {
        for( Node* p = m_kopf.m_next; p; p = p-&gt;m_next )
        {
            out &lt;&lt; p-&gt;m_value &lt;&lt; delim;
        }
        return out;
    }

private:
    // Kopieren z.Zt. nicht vorgesehen; -&gt; &quot;Regel der drei&quot;
    SList( const SList&amp; );
    SList&amp; operator=( const SList&amp; );

    // --   Member
    Node m_kopf;
    Node* m_ende;
};

int main()
{
    SList A;
    A.push_back(20);
    A.push_back(200);

    return 0;
}
</code></pre>
<p>Es gibt anfangs ein &quot;m_kopf&quot; Node Objekt, und einen Node Zeiger namens &quot;m_ende&quot;.<br />
&quot;m_kopf&quot; wird mit 0 initialisiert, m_ende zeigt auf m_kopf.</p>
<p>// m_kopf --&gt; a --&gt; b --&gt; c --&gt; d --&gt; m_ende<br />
// ^-----------------------------------------------|</p>
<p>Doch jetzt wenn ich zur Funktion push_back() gehe, dann blick ich nicht mehr durch.</p>
<pre><code class="language-cpp">void push_back( const value_type&amp; x ) // ersetzt das einfuegen() was ein anhaengen() ist
    {
        m_ende-&gt;m_next = new Node( x );
        m_ende = m_ende-&gt;m_next;
    }
</code></pre>
<p>Der Node Zeiger &quot;m_next&quot; aus &quot;m_kopf&quot; hat nun ein neus Node Objekt auf dem HEap erstelle und Zeigt darauf:<br />
m_kopf.m_next --&gt; neues Objekt<br />
Und die Elementvariable &quot;m_next&quot; vom Zeiger &quot;m_next&quot; zeigt auf NULL. (konstruktor)<br />
Dann übernimmt m_ende die Adresse von dem neuen Objekt (m_next).<br />
Trotzdem check ich net was das nun alles bringt. Da soll sich doch so eine Zeigerkettet ergeben....mh ich hab glaub irgendwas nicht richtig verstanden!? Kann mir jemand des alles nochmal n bissel erklären, den irgendwas mach ich ziemlich falsch in meinem Kopf.</p>
<p><a href="http://www.pictureupload.de/originals/pictures/041107125828_mein_gehirn.JPG" rel="nofollow">http://www.pictureupload.de/originals/pictures/041107125828_mein_gehirn.JPG</a></p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1397411</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1397411</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Sun, 04 Nov 2007 11:59:11 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Sun, 04 Nov 2007 16:54:20 GMT]]></title><description><![CDATA[<p>Hallo Stromberg,</p>
<p>mal angenommen, die Liste ist leer. Dann haben wir folgende Situation:</p>
<pre><code>m_ende
    |
    v
 +-------+
 | m_kopf|
 |   0   |  
 +-------+
</code></pre>
<p>Also es gibt ein Node-Element m_kopf, dessen Member m_next den Wert 0 (bzw. NIL Not In List) hat und der Member m_ende der Liste zeigt auf eben dieses Node-Objekt m_kopf.</p>
<p>Jetzt wird z.B. push_back( x1 ) aufgerufen. In der ersten Zeile geschieht</p>
<pre><code class="language-cpp">m_ende-&gt;m_next = new Node( x );
</code></pre>
<p>Dann ergibt sich folgendes Bild</p>
<pre><code>m_ende
    |
    v
 +-------+   +-&gt;+-------+
 | m_kopf|   |  |  x1   |
 |  p1-------+  |  0    |
 +-------+      +-------+
</code></pre>
<p>'new Node( x )' legt ein Knotenobjekt auf dem Heap in diesem Fall mit dem Value x1. Beachte nun, dass m_ende auf m_kopf zeigt und m_ende-&gt;m_next der Member m_next von m_kopf ist. Diesem m_next wird die Adresse (p1) des Nodes von x1 zugewiesen.</p>
<p>In der zweiten Zeile geschieht</p>
<pre><code class="language-cpp">m_ende = m_ende-&gt;m_next;
</code></pre>
<p>Also m_ende bekommt jetzt den Wert der Adresse des neuen Knoten zugewiesen - also zeigt m_ende auf den neuen Knoten</p>
<pre><code>m_ende
                   |
                   v
 +-------+   +-&gt;+-------+
 | m_kopf|   |  |  x1   |
 |  p1-------+  |  0    |
 +-------+      +-------+
</code></pre>
<p>Beim nächsten push_back (z.B. push_back( x2 )) geht es genauso weiter. Nach der ersten Zeile ist die Situation</p>
<pre><code>m_ende
                   |
                   v
 +-------+   +-&gt;+-------+   +-&gt;+-------+
 | m_kopf|   |  |  x1   |   |  |  x2   |
 |  p1-------+  |  p2-------+  |  0    |
 +-------+      +-------+      +-------+
</code></pre>
<p>.. und mit der zweiten Zeile wird m_ende auf den nächsten Knoten verschoben - also immer auf den Letzten.</p>
<pre><code>m_ende
                                  |
                                  v
 +-------+   +-&gt;+-------+   +-&gt;+-------+
 | m_kopf|   |  |  x1   |   |  |  x2   |
 |  p1-------+  |  p2-------+  |  0    |
 +-------+      +-------+      +-------+
</code></pre>
<p>An dieser push_back-Methode sieht man auch den Vorteil des Dummy-Kopf-Elements, welches kein Element der eigentlichen Liste ist. Wenn man statt des Elements m_kopf nur einen Pointer auf das erste Element hat - also Node* m_head; - so hätte m_ende den Wert 0 (bzw. NIL), wenn die Liste leer wäre. Also müsste man innerhalb von push_back diesen Fall immer abfragen. Also so etwa</p>
<pre><code class="language-cpp">void push_back( const value_type&amp; x )
    {
        if( m_head )       //  Node* m_head;
        {
            // Liste ist nicht leer -&gt; m_ende ist garantiert belegt
            // Code wie oben
            m_ende-&gt;m_next = new Node( x );
            m_ende = m_ende-&gt;m_next;
        }
        else
        {
            // Liste ist leer also Sonderbehandlung
            m_head = new Node( x );
            m_ende = m_head;
        }
    }
</code></pre>
<p>So eine Konstruktion mit dem Dummy-Element nennt man auch ein Sentinel (engl. Wächter) (siehe auch bei <a href="http://de.wikipedia.org/wiki/Verkettete_Liste#Liste_mit_Listenkopf" rel="nofollow">Wiki</a>)</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1397608</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1397608</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Sun, 04 Nov 2007 16:54:20 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Sun, 04 Nov 2007 18:17:09 GMT]]></title><description><![CDATA[<p>Könntest du mir auch noch die clear() Funktion erklären, weil diese for-Schleife versteh ich mal gar nicht, warum ist die 3te Lücke leer.</p>
<pre><code class="language-cpp">void clear() // ersetzt das ende() 
    { 
        for( Node* p = m_kopf.m_next; p; ) 
        { 
            Node* tmp = p; 
            p = p-&gt;m_next; 
            delete tmp; 
        } 
        m_kopf.m_next = 0; 
        m_ende = &amp;m_kopf; 
    }
</code></pre>
<p>Das &quot;m_ende=&amp;m_kopf&quot; ist aber dann doch nicht mehr wichtig zum schluss oder?</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1397660</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1397660</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Sun, 04 Nov 2007 18:17:09 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Sun, 04 Nov 2007 20:45:34 GMT]]></title><description><![CDATA[<p>Noch was, was hältst du von dieser Lösung, weil deine versteh ich (noch) nicht.</p>
<pre><code class="language-cpp">List::~List()
{
    cout &lt;&lt; &quot;Destruktor List\n&quot;;
    Node *temp=&amp;m_kopf;
    Node *save;
    while(temp-&gt;m_next!=0)
    {
        cout &lt;&lt; &quot;Entferne Node Objekt\n&quot;;
        save=temp-&gt;m_next;
        delete temp;
        temp=0;
        temp=save;
    }
    m_ende=&amp;m_kopf;
}
</code></pre>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1397752</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1397752</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Sun, 04 Nov 2007 20:45:34 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Sun, 04 Nov 2007 23:11:39 GMT]]></title><description><![CDATA[<p>Hallo Stromberg,</p>
<p>zur clear-Methode: mal angenommen die Liste hat 2 Elemente und es wird clear() aufgerufen. Die Ausgangssituation ist wieder</p>
<pre><code>m_ende
                                  |
                                  v
 +-------+   +-&gt;+-------+   +-&gt;+-------+
 | m_kopf|   |  |  x1   |   |  |  x2   |
 |  p1-------+  |  p2-------+  |  0    |
 +-------+      +-------+      +-------+
</code></pre>
<pre><code class="language-cpp">void clear()
{         
    for( Node* p = m_kopf.m_next; p; )
    {
        Node* tmp = p;
        p = p-&gt;m_next;
        delete tmp;
</code></pre>
<p>Die Variable 'p' wird mit m_kopf.m_next initialisiert - enthält also den Wert 'p1' - ungleich 0, also wird die Schleife nicht abgebrochen. In Zeile 5 wird der Zeiger in 'tmp' gemerkt und anschließend in Zeile 6 die Variable p auf den nächsten Knoten gesetzt. Vor der Zeile 7 haben wir dann folgendes:</p>
<pre><code>tmp           p   m_ende
                   |            |    |
                   v            v    v
 +-------+   +-&gt;+-------+   +-&gt;+-------+
 | m_kopf|   |  |  x1   |   |  |  x2   |
 |  p1-------+  |  p2-------+  |  0    |
 +-------+      +-------+      +-------+
</code></pre>
<p>jetzt geschieht 'delete tmp' - d.h. der Knoten mit x1 wird gelöscht. 'p' ist immer noch ungleich 0 - sie hat ja den Wert 'p2' - die Schleife wird erneut betreten und vor der Zeile 7 sieht es jetzt so aus</p>
<pre><code>tmp  m_ende   p == 0
                                |    |
                                v    v
 +-------+   +-&gt;?              +-------+
 | m_kopf|   |                 |  x2   |
 |  p1-------+                 |  0    |
 +-------+                     +-------+
</code></pre>
<p>Durch das 'Weiterschalten' von 'P' hat diese Variable den Wert 0 angenommen - von p2-&gt;m_next. Vorher wurde 'p' nach 'tmp' kopiert, die jetzt immer noch auf den Knoten mit x2 zeigt.<br />
In Zeile 7 wird mit 'delete tmp' der Knoten mit x2 gelöscht.<br />
Übrig bleiben jetzt zwei 'hängende Zeiger' nämlich m_kop.m_next der auf ein p1 zeigt wo kein Knoten x1 mehr ist und 'm_ende' der auf ein nicht mehr vorhandenes x2 zeigt.<br />
Mit</p>
<pre><code class="language-cpp">m_kopf.m_next = 0;
        m_ende = &amp;m_kopf;
</code></pre>
<p>wird das bereinigt und das ist auch notwendig, denn mit dem nächsten push_back z.B. wird ja auf m_ende-&gt;m_next also dann auf den Next-Pointer in m_kopf zugegriffen und das natürlich definiert sein.</p>
<p>Jetzt zu Deinem Code</p>
<p>Stromberg schrieb:</p>
<blockquote>
<p>Noch was, was hältst du von dieser Lösung, weil deine versteh ich (noch) nicht.</p>
<pre><code class="language-cpp">List::~List()
{
    cout &lt;&lt; &quot;Destruktor List\n&quot;;
    Node *temp=&amp;m_kopf;
    Node *save;
    while(temp-&gt;m_next!=0)
    {
        cout &lt;&lt; &quot;Entferne Node Objekt\n&quot;;
        save=temp-&gt;m_next;
        delete temp;
        temp=0;
        temp=save;
    }
    m_ende=&amp;m_kopf;
}
</code></pre>
</blockquote>
<p>Angenommen wir beginnen wieder mit der Liste mit den beiden Elementen x1 und x2 dann erhält man vor Zeile 10 diese Situation</p>
<pre><code>temp           save          m_ende
    |              |              |
    v              v              v
 +-------+   +-&gt;+-------+   +-&gt;+-------+
 | m_kopf|   |  |  x1   |   |  |  x2   |
 |  p1-------+  |  p2-------+  |  0    |
 +-------+      +-------+      +-------+
</code></pre>
<p>Dann rufst Du 'delete temp' versuchst also das Kopf-Element vom Heap zu entfernen. Dies ist aber ein Member der Liste und im besten Fall beendet Dein Memory-Management hier das Programm.</p>
<p>Stromberg schrieb:</p>
<blockquote>
<p>... weil diese for-Schleife versteh ich mal gar nicht, warum ist die 3te Lücke leer.</p>
</blockquote>
<p>nun warum nicht - was sollte darin stehen?</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1397804</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1397804</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Sun, 04 Nov 2007 23:11:39 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Sun, 04 Nov 2007 23:14:13 GMT]]></title><description><![CDATA[<p>Wow Werner <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="👍"
    /><br />
Hast dir ja viel Mühe dabei gegeben, vllt sollte das in die FAQ gesetzt werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1397806</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1397806</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Sun, 04 Nov 2007 23:14:13 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Mon, 05 Nov 2007 14:41:30 GMT]]></title><description><![CDATA[<p>Aber wenns so ist, dann gehts doch:</p>
<pre><code class="language-cpp">List::~List()
{
    cout &lt;&lt; &quot;Destruktor List\n&quot;;
    Node *temp=m_head.m_next;
    Node *save;
    while(temp-&gt;m_next!=0)
    {
        cout &lt;&lt; &quot;Entferne Node Objekt\n&quot;;
        save=temp-&gt;m_next;
        delete temp;
        temp=0;
        temp=save;
    }
    m_end=&amp;m_head;
}
</code></pre>
<p>??? Also wenn das erste &quot;Node *temp=m_head.m_next;&quot; ist.<br />
<a href="http://www.pictureupload.de/pictures/051107153523_mein_gehirn.JPG" rel="nofollow">http://www.pictureupload.de/pictures/051107153523_mein_gehirn.JPG</a> &lt;-- so stell ich mir das vor.</p>
<p>Jetzt schau ich mir mal deine Erklärung an.<br />
Schon mal im Voraus ein Dankeschön für die große Mühe.</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1398077</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1398077</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Mon, 05 Nov 2007 14:41:30 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Tue, 06 Nov 2007 16:24:56 GMT]]></title><description><![CDATA[<p>Werner biste noch da?</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1398795</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1398795</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Tue, 06 Nov 2007 16:24:56 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Tue, 06 Nov 2007 22:12:00 GMT]]></title><description><![CDATA[<p>Stromberg schrieb:</p>
<blockquote>
<p>Werner biste noch da?</p>
</blockquote>
<p>Öh - ja klar - nicht ständig aber immer wieder.</p>
<p>Erwartest Du eine Antwort? ... ich sehe keine Frage <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>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1398937</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1398937</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Tue, 06 Nov 2007 22:12:00 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Wed, 07 Nov 2007 10:27:04 GMT]]></title><description><![CDATA[<p>Hallo Stromberg, dein Schleifenbedingung ist falsch:</p>
<pre><code class="language-cpp">while(temp-&gt;m_next!=0) // &lt;- falsch
</code></pre>
<p>Du überprüfst nur, ob der Member 'next' 0 ist, aber nicht ob die eigentliche Variable 'temp' 0 ist.</p>
<p>Wenn du die for-Schleife von Werner eigenartig findest, dann kann man sie auch als while-Schleife formulieren:</p>
<pre><code class="language-cpp">Node* p = m_kopf.m_next;
while(p) // entspricht: p != 0
{
   Node* tmp = p;
   p = p-&gt;m_next;
   delete tmp;
}
</code></pre>
<p>Der Vorteil mit der for-Schleife bezieht sich auf das automatische Löschen der Variable p nach der Schleife (und nicht erst am Ende des umgebenden Blocks).</p>
<p>Eigentlich würde man ja die &quot;Inkrementieranweisung&quot; als 3. Parameter der for-Schleife angeben, aber da evtl. nach dem Löschen von 'tmp' der Inhalt schon wieder anderweitig verwendet sein könnte (in Multithreading/-tasking-Systemen) muß zuerst 'p' auf den neuen Wert gesetzt werden und danach erst das Objekt in 'tmp' löschen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1398986</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1398986</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Wed, 07 Nov 2007 10:27:04 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Wed, 07 Nov 2007 21:17:11 GMT]]></title><description><![CDATA[<p>Ich hab Werner's Beispiel jetzt schon verstanden. War bloß anfangs verwirrt, weil ich immer so nä standard for schleife benutze und zwar:<br />
(int i=0;i&lt;X;i++)...deshalb hat mich des anfangs bissel verwirrt, weil mir mein &quot;++&quot; gefehlt hat <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> Aber jetzt is alles klar.</p>
<p>Bei meinem Beispiel müsste es dann aber doch dann so gehen:</p>
<pre><code class="language-cpp">List::~List()
{
    cout &lt;&lt; &quot;Destruktor List\n&quot;;
    Node *temp=m_head.m_next;
    Node *save;
    while(temp!=0)
    {
        cout &lt;&lt; &quot;Entferne Node Objekt\n&quot;;
        save=temp-&gt;m_next;
        delete temp;
        temp=0;
        temp=save;
    }
    m_end=&amp;m_head;
}
</code></pre>
<p>????????</p>
<p>Das hier war natürlich unsinnig:</p>
<pre><code class="language-cpp">while(temp-&gt;m_next!=0) // &lt;- falsch
</code></pre>
<p>sowas fällt mir aber irgendwie nie selber auf :).</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1399462</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1399462</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Wed, 07 Nov 2007 21:17:11 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Thu, 08 Nov 2007 22:01:22 GMT]]></title><description><![CDATA[<p>Wie kann ich den überprüfen ob alles korrekt gelöscht wird, und nix überig bleibt und eventuell Speicherlücken entstehen?</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1400060</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1400060</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Thu, 08 Nov 2007 22:01:22 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Thu, 08 Nov 2007 22:29:24 GMT]]></title><description><![CDATA[<p>nur durch nen test, also meines wissens nach. und zwar ist es nen doppelter test (so mache ich es immer). erstens nen event ect reindrücken ob mit scanf oder wer weis, das löst das erstellen von x elementen in der kette aus (sollten genug sein das auch ordentlich speicher drauf geht). alle listenelemte als extrapointer wo speichern nach der erstellung und taskmgr aufmachen. dann geht es los prog starten im task speicher anschauen, dann erstellung auslösen und schauen wieviel speicher extra gefressen wird. danach löschen auslösen am ende muss wieder gleicher speicherwert im tastmgr stehen, desweiteren kannst dann in dem extraarray der pointer prüfen ob an einer speicheradresse wirklich noch ein element liegt oder nicht. gibt sicher eine wesentlich bessere methode aber die ist mir nicht bekannt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> . Nichts desto trotz ist dennoch mit meiner methode wirklich feststellbar ob wirklich alles wieder gelöscht wurde, bis auf jedes einzellne element ist es so nachprüfbar. das mit den extra pointerarray kannst weglassen wenn dich das nicht so genau interessiert der task zeigt ja die kb an also ziemlich genau wodurch du erkennen kannst ob dein prog nach dem löschen mehr speicher benutzt als vor der erstellung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1400067</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1400067</guid><dc:creator><![CDATA[oelsni]]></dc:creator><pubDate>Thu, 08 Nov 2007 22:29:24 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Liste on Fri, 09 Nov 2007 21:12:34 GMT]]></title><description><![CDATA[<p>Stromberg schrieb:</p>
<blockquote>
<p>Wie kann ich den überprüfen ob alles korrekt gelöscht wird, und nix überig bleibt und eventuell Speicherlücken entstehen?</p>
</blockquote>
<p>Es gibt dafür Tools - z.B. <a href="http://en.wikipedia.org/wiki/Boundschecker" rel="nofollow">Boundschecker</a> - oder selbst die MS-Visual-Studio-Umgebung oder <a href="http://www.boost.org/libs/test/doc/index.html" rel="nofollow">boost.test</a> können Speicherlücken detektieren. Ansonsten kann man sich auch selbst mit einer Testklasse behelfen.</p>
<p>Zunächst muss man aus der Liste ein Template machen ..</p>
<pre><code class="language-cpp">template&lt; typename T &gt;
class SList
{
public:
    typedef T value_type;
</code></pre>
<p>dann kann man sich ein eigenes Testprogramm schreiben</p>
<pre><code class="language-cpp">#include &quot;List.h&quot;
#include &lt;iostream&gt;

class LifeCtrl
{
public:
    LifeCtrl() { ++m_cnt; }
    ~LifeCtrl() { --m_cnt; }
    LifeCtrl( const LifeCtrl&amp; ) { ++m_cnt; }
    static int m_cnt; // Zähler für alle aktuell existierenden LifeCtrl-Objekte
};
int LifeCtrl::m_cnt = 0;

int main()
{
    using namespace std;
    {
        SList&lt; LifeCtrl &gt; l;
        for( int i=0; i&lt;3; ++i )
            l.push_back( LifeCtrl() );
        l.clear();
        cout &lt;&lt; &quot;nach clear: Anzahl LifeCtrl-Objekte = &quot; &lt;&lt; LifeCtrl::m_cnt &lt;&lt; endl;
        for( int i=0; i&lt;3; ++i )
            l.push_back( LifeCtrl() );
        // weiter Aktionen auf der Liste ... oder weitere Listen

    }   // damit sollte der Destruktor aufgerufen werden
    cout &lt;&lt; &quot;Ende: Anzahl LifeCtrl-Objekte = &quot; &lt;&lt; LifeCtrl::m_cnt &lt;&lt; endl;
    return 0;
}
</code></pre>
<p>Die erwartete Ausgabe wäre:</p>
<pre><code>nach clear: Anzahl LifeCtrl-Objekte = 1
Ende: Anzahl LifeCtrl-Objekte = 0
</code></pre>
<p>Wenn die Liste mit clear() gelöscht wird, so bleibt das Sentinel-Objekt zurück, da die Liste selbst noch existiert. Wird der Destruktor der Liste aufgerufen - mit Verlassen des Scopes - so darf kein LifCtrl-Objekt mehr übrig bleiben - d.h. die Anzahl muss 0 sein.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1400596</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1400596</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Fri, 09 Nov 2007 21:12:34 GMT</pubDate></item></channel></rss>