<?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[Container-Daten nach clear() noch im Iterator vorhanden]]></title><description><![CDATA[<p>Hallo,</p>
<p>mich wundert, daß im folgenden Konstrukt die Daten noch im Speicher sind.<br />
Erhält ein Iterator beim konstruieren alle Daten des Containers?</p>
<pre><code class="language-cpp">vector&lt;int&gt; v;
    // vector&lt;int&gt;::iterator Iter=v.begin(); // führt natürlich zum Absturz
    v.push_back(1);
    v.push_back(2);

    vector&lt;int&gt;::iterator Iter=v.begin();

    v.clear();      // Jetzt sollten alle Daten aus dem Speicher sein

    Iter++;   

    cout &lt;&lt; *Iter &lt;&lt; endl;      // Ausgabe: &quot;2&quot;. Also muß noch eine Kopie im Speicher liegen
                                // Iter wurde erhöht, muss beim konstr. also alle daten haben

    cout &lt;&lt; v.size() &lt;&lt; endl;   // Ausgabe: &quot;0&quot;. So wie es sein sollte
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/226192/container-daten-nach-clear-noch-im-iterator-vorhanden</link><generator>RSS for Node</generator><lastBuildDate>Thu, 01 Oct 2026 02:30:11 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/226192.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 30 Oct 2008 14:25:04 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Container-Daten nach clear() noch im Iterator vorhanden on Thu, 30 Oct 2008 14:25:04 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>mich wundert, daß im folgenden Konstrukt die Daten noch im Speicher sind.<br />
Erhält ein Iterator beim konstruieren alle Daten des Containers?</p>
<pre><code class="language-cpp">vector&lt;int&gt; v;
    // vector&lt;int&gt;::iterator Iter=v.begin(); // führt natürlich zum Absturz
    v.push_back(1);
    v.push_back(2);

    vector&lt;int&gt;::iterator Iter=v.begin();

    v.clear();      // Jetzt sollten alle Daten aus dem Speicher sein

    Iter++;   

    cout &lt;&lt; *Iter &lt;&lt; endl;      // Ausgabe: &quot;2&quot;. Also muß noch eine Kopie im Speicher liegen
                                // Iter wurde erhöht, muss beim konstr. also alle daten haben

    cout &lt;&lt; v.size() &lt;&lt; endl;   // Ausgabe: &quot;0&quot;. So wie es sein sollte
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1607237</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1607237</guid><dc:creator><![CDATA[XHansWurstX]]></dc:creator><pubDate>Thu, 30 Oct 2008 14:25:04 GMT</pubDate></item><item><title><![CDATA[Reply to Container-Daten nach clear() noch im Iterator vorhanden on Thu, 30 Oct 2008 14:26:51 GMT]]></title><description><![CDATA[<p>Der Speicher wird nicht leer gemacht oder auf 0 gesetzt. Der Vektor wird nur wieder auf den Zustand &quot;leer&quot; gesetzt.<br />
Was Du da machst, ist nicht erlaubt, und der Zustand ist undefiniert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1607239</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1607239</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Thu, 30 Oct 2008 14:26:51 GMT</pubDate></item><item><title><![CDATA[Reply to Container-Daten nach clear() noch im Iterator vorhanden on Thu, 30 Oct 2008 14:28:23 GMT]]></title><description><![CDATA[<p>XHansWurstX schrieb:</p>
<blockquote>
<p>mich wundert, daß im folgenden Konstrukt die Daten noch im Speicher sind.</p>
</blockquote>
<p>Clear löscht nicht zwangsweise die Elementinhalte, dies bekommst du hin in dem du den vector entsprechend verkleinerst. Und ein Iteratorzugriff nach irgendeiner Form einer Änderung des Vectors ist eh undefiniert.</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1607242</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1607242</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Thu, 30 Oct 2008 14:28:23 GMT</pubDate></item><item><title><![CDATA[Reply to Container-Daten nach clear() noch im Iterator vorhanden on Thu, 30 Oct 2008 14:28:28 GMT]]></title><description><![CDATA[<p>Tachyon schrieb:</p>
<blockquote>
<p>Was Du da machst, ist nicht erlaubt, und der Zustand ist undefiniert.</p>
</blockquote>
<p>Ich denke mal, Du meinst die Zeilen nach dem clear() <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/1607243</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1607243</guid><dc:creator><![CDATA[XHansWurstX]]></dc:creator><pubDate>Thu, 30 Oct 2008 14:28:28 GMT</pubDate></item><item><title><![CDATA[Reply to Container-Daten nach clear() noch im Iterator vorhanden on Thu, 30 Oct 2008 14:31:14 GMT]]></title><description><![CDATA[<p>XHansWurstX schrieb:</p>
<blockquote>
<p>Erhält ein Iterator beim konstruieren alle Daten des Containers?</p>
</blockquote>
<p>Wie sieht's damit aus? Scheint ja so zu sein...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1607245</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1607245</guid><dc:creator><![CDATA[XHansWurstX]]></dc:creator><pubDate>Thu, 30 Oct 2008 14:31:14 GMT</pubDate></item><item><title><![CDATA[Reply to Container-Daten nach clear() noch im Iterator vorhanden on Thu, 30 Oct 2008 14:31:33 GMT]]></title><description><![CDATA[<p>XHansWurstX schrieb:</p>
<blockquote>
<p>Tachyon schrieb:</p>
<blockquote>
<p>Was Du da machst, ist nicht erlaubt, und der Zustand ist undefiniert.</p>
</blockquote>
<p>Ich denke mal, Du meinst die Zeilen nach dem clear() <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>Die Operationen, die Du auf dem Iterator durchführst. &quot;Zustand&quot; ist auch nicht das richtige Wort. Man sollte eher sagen, dass der Iterator ungültig ist.<br />
Es gibt aber seitens des Vektors oder des Iterators keine Checks auf Gültigkeit. Daher &quot;geht&quot; das, jedoch ist das Programmverhalten an der Stelle undefiniert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1607246</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1607246</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Thu, 30 Oct 2008 14:31:33 GMT</pubDate></item><item><title><![CDATA[Reply to Container-Daten nach clear() noch im Iterator vorhanden on Thu, 30 Oct 2008 14:34:06 GMT]]></title><description><![CDATA[<p>Btw ist mir klar, daß ich solche Zeilen in keinen Code einfüge <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>
<p>Es ist mir nur zufällig aufgefallen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1607248</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1607248</guid><dc:creator><![CDATA[XHansWurstX]]></dc:creator><pubDate>Thu, 30 Oct 2008 14:34:06 GMT</pubDate></item><item><title><![CDATA[Reply to Container-Daten nach clear() noch im Iterator vorhanden on Thu, 30 Oct 2008 15:15:24 GMT]]></title><description><![CDATA[<p>XHansWurstX schrieb:</p>
<blockquote>
<p>XHansWurstX schrieb:</p>
<blockquote>
<p>Erhält ein Iterator beim konstruieren alle Daten des Containers?</p>
</blockquote>
<p>Wie sieht's damit aus? Scheint ja so zu sein...</p>
</blockquote>
<p>Ein Iterator enthält keinerlei Daten sondern nur das für den Elementzugriff wichtige. Im einfachsten Fall kann ein Iterator ein dummer Zeiger auf den Speicherbereich sein (Im Falle des std::vector sogar nicht unwahrscheinlich).</p>
<p>Stell dir die Situation wie Folgt vor:</p>
<pre><code class="language-cpp">std::vector&lt;int&gt; intContainer;

// Ein vector wird erstellt, dieser wird auf eine Initialgröße, sagen wir mal 3
// gesetzt. Sprich: Platz für 3 ints, size wird mit 0 angegeben (Der Platz ist
// aber reserviert und enthält auch schon im initialzustand Werte:
// size     : 0
// capacity : 3
// Daten    : [0, 0, 0]

intContainer.push_back(4);
intContainer.push_back(5);
intContainer.push_back(6);

// size     : 3
// capacity : 3
// Daten    : [4, 5, 6]

std::vector&lt;int&gt;::iterator it = intContainer.begin(); 

// Der Iterator verweist auf den aktuellen Beginn. In der Regel ist das beim
// vector einfach ein Zeiger auf das erste Element

intContainer.push_back(7);

// Nun reicht der Speicherbereich nicht mehr aus, muss also neualloziert
// werden (z.B. mit der doppelten capazity)
// size     : 4
// capacity : 6
// Daten    : [4, 5, 6, 7, 0, 0] NEUER SPEICHERBEREICH!

int a = (*begin); // Fehler!

// Der Iterator ist ungültig, er zeigt weiterhin auf den alten Speicherbereich
// ...

begin = intContainer.begin(); //Dieser wäre gültig
intContainer.clear();

// clear setzt zwar den &quot;size&quot; auf 0. Löscht aber nicht zwangsweise die
// Elemente...
// size     : 0
// capacity : 6
// Daten    : [4, 5, 6, 7, 0, 0]

// Nun ist begin auch wieder ungültig, er mag auf die noch vorhandenen
// Elemente zeigen, aber vermutlich ist begin nun gleich intContainer.end()
</code></pre>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1607266</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1607266</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Thu, 30 Oct 2008 15:15:24 GMT</pubDate></item><item><title><![CDATA[Reply to Container-Daten nach clear() noch im Iterator vorhanden on Thu, 30 Oct 2008 15:38:23 GMT]]></title><description><![CDATA[<p>ein clear() im vector heißt, dass der Destruktor der entsprechenden Elemente aufgerufen wird und dass damit, semantisch gesehen, die entsprechenden Elemente nicht mehr existieren. Daher sind auch die Iteratoren auf die Elemente ungültig.<br />
Soweit zur Theorie.<br />
Was in der Praxis geschieht, ist durch den Standrad nicht festgelegt. Iteratoren werden intern meist mit Zeigern implementiert. Man könnte also dafür sorgen, dass sie auf irgendein gültiges Element zeigen oder die Zeiger auf 0 setzen um anzuzeigen dass sie ungültig sind. Dazu müsste aber der Container jeden iterator kennen der auf eines seiner Elemente verweist, und die Änderungen der iteratoren nehmen auch Zeit in Anspruch. Nach der C++-Philosophie &quot;don't pay for what you don't need&quot; wird das alles sein gelassen, damit verweisen die Pointer weiterhin auf den Speicherbereich wo vorher mal das Element war. Da weiterhin die Destruktoren der Elemente nicht unbedingt was tun müssen, heißt das, dass meistens (bzw. fast immer) nach der Zerstörung eines Objektes dessen Bitmuster weiterhin im Speicher stehn bleibt. Fazit: der ungültige Iterator greift über einen Pointer auf T auf Speicher zu, der &quot;zufälligerweise&quot; das Bitmuster eines T enthält und es sieht so aus als ob da tatsächlich noch ein Objekt vom Typ T existiert. Der Speicher gehört weiterhin dem vector (der gibt ihn nicht frei), ist für den aber einfach uninitialisierter Speicher. Du könntest jetzt noch einen Schritt weiter gehen:</p>
<pre><code class="language-cpp">std::vector&lt;T&gt;::iterator foo(T t1, T t2)
{
  std::vector&lt;T&gt; bar;
  bar.push_back( t1 );
  bar.push_back( t2 ); //zwei Objekte einfügen
  std::vector&lt;T&gt;::iterator it = bar.begin();
  ++it; //zeigt aufs zweite Element
  bar.clear();  //it ist ungültig, der Speicher gehört noch bar
  return it;
}

int main()
{
  T t1(&quot;bla&quot;);
  T t2(&quot;blubb&quot;);
  std::vector&lt;T&gt;::iterator testIter = foo(t1, t2);
  T t = *testIter; 
}
</code></pre>
<p>testIter ist ungültig und zeigt sogar auf Speicher, der niemandem gehört -der vector bar hat ihn am Ende von foo() im Destruktor freigegeben. Trotzdem sind die chancen nicht schlecht, dass t problemlos initialisiert wurde mit den Werten von t2, weil die immernoch in dem Speicher standen auch nach der Freigabe.</p>
<p>Aber: all das ist nicht garantiert! Die Implementation darf sehr wohl den internen Pointer des ungültigen Iterators verändern, oder nach der Zerstörung der vector-Elemente deren Speicher auf 0 setzen (z.B. zu Debugzwecken), oder der Speicher wird nach der Freigabe ans Betriebssystem zurückgegeben und anderweitig verwendet, oder...</p>
<p>Zusammengefasst: das Arbeiten mit ungültigen iteratoren erzeugt undefiniertes verhalten. &quot;<em><strong>don't try this at home</strong></em>&quot; <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/1607285</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1607285</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Thu, 30 Oct 2008 15:38:23 GMT</pubDate></item><item><title><![CDATA[Reply to Container-Daten nach clear() noch im Iterator vorhanden on Thu, 30 Oct 2008 15:42:15 GMT]]></title><description><![CDATA[<p>Danke, sehr informative/ interessante Antworten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1607288</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1607288</guid><dc:creator><![CDATA[XHansWurstX]]></dc:creator><pubDate>Thu, 30 Oct 2008 15:42:15 GMT</pubDate></item></channel></rss>