<?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[Ist Iterieren über Elemente, die gerade gelöscht werden UB?]]></title><description><![CDATA[<p>Mir fliegt gerade mein Code um die Ohren und ich habe folgendes Konstrukt im Verdacht:</p>
<pre><code>#include &lt;vector&gt;
#include &lt;iostream&gt;
#include &lt;memory&gt;

struct Foo;

std::vector&lt;std::unique_ptr&lt;Foo&gt;&gt; v;

struct Foo{
	void print(){
		std::cout &lt;&lt; this;
	}
	~Foo(){
		for (auto &amp;e : v){ //iterieren über Elemente, die gerade gelöscht werden
			e-&gt;print();
		}
	}
};

int main(){
	v.emplace_back(std::make_unique&lt;Foo&gt;());
	v.emplace_back(std::make_unique&lt;Foo&gt;());
	v.emplace_back(std::make_unique&lt;Foo&gt;());
	v.clear();
}
</code></pre>
<p>UB oder OK?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/327101/ist-iterieren-über-elemente-die-gerade-gelöscht-werden-ub</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Jul 2026 20:22:14 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/327101.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 23 Jul 2014 16:04:38 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Ist Iterieren über Elemente, die gerade gelöscht werden UB? on Wed, 23 Jul 2014 16:04:38 GMT]]></title><description><![CDATA[<p>Mir fliegt gerade mein Code um die Ohren und ich habe folgendes Konstrukt im Verdacht:</p>
<pre><code>#include &lt;vector&gt;
#include &lt;iostream&gt;
#include &lt;memory&gt;

struct Foo;

std::vector&lt;std::unique_ptr&lt;Foo&gt;&gt; v;

struct Foo{
	void print(){
		std::cout &lt;&lt; this;
	}
	~Foo(){
		for (auto &amp;e : v){ //iterieren über Elemente, die gerade gelöscht werden
			e-&gt;print();
		}
	}
};

int main(){
	v.emplace_back(std::make_unique&lt;Foo&gt;());
	v.emplace_back(std::make_unique&lt;Foo&gt;());
	v.emplace_back(std::make_unique&lt;Foo&gt;());
	v.clear();
}
</code></pre>
<p>UB oder OK?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2410120</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2410120</guid><dc:creator><![CDATA[nwp3]]></dc:creator><pubDate>Wed, 23 Jul 2014 16:04:38 GMT</pubDate></item><item><title><![CDATA[Reply to Ist Iterieren über Elemente, die gerade gelöscht werden UB? on Wed, 23 Jul 2014 16:27:36 GMT]]></title><description><![CDATA[<p>Er greift in der for-Schleife auf gelöschte Objekte zu, deswegen crasht es <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="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2410122</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2410122</guid><dc:creator><![CDATA[nwp3]]></dc:creator><pubDate>Wed, 23 Jul 2014 16:27:36 GMT</pubDate></item><item><title><![CDATA[Reply to Ist Iterieren über Elemente, die gerade gelöscht werden UB? on Wed, 23 Jul 2014 16:46:44 GMT]]></title><description><![CDATA[<p>Wenn man</p>
<pre><code>v.clear();
</code></pre>
<p>durch</p>
<pre><code>while (v.size())
    v.pop_back();
</code></pre>
<p>ersetzt, dann wird das Problem umgangen. Ausgesprochen unschön.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2410124</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2410124</guid><dc:creator><![CDATA[nwp3]]></dc:creator><pubDate>Wed, 23 Jul 2014 16:46:44 GMT</pubDate></item><item><title><![CDATA[Reply to Ist Iterieren über Elemente, die gerade gelöscht werden UB? on Wed, 23 Jul 2014 17:17:32 GMT]]></title><description><![CDATA[<p>Ist doch klar, was passiert: Du greifst auf destructed unique_ptrs zu.</p>
<pre><code class="language-cpp">v.emplace_back(std::make_unique&lt;Foo&gt;());
    v.emplace_back(std::make_unique&lt;Foo&gt;());
    v.emplace_back(std::make_unique&lt;Foo&gt;());
    v.clear();

/* Erstes Foo löschen:
   | v[0].~unique_ptr();
   | | v[0]-&gt;print(); // ok, weil v[0] noch nicht deleted hat
   | | v[1]-&gt;print();
   | | v[2]-&gt;print();
   | | delete v[0].get(); // Speicher freigeben

   Zweites Foo löschen:
   | v[1].~unique_ptr();
   | | v[0]-&gt;print(); // bäm
   | | v[1]-&gt;print();
   | | v[2]-&gt;print();
   | | delete v[1].get(); // Speicher freigeben

   Drittes Foo löschen:
   | v[2].~unique_ptr();
   | | v[0]-&gt;print(); // bäm
   | | v[1]-&gt;print(); // bäm
   | | v[2]-&gt;print();
   | | delete v[2].get(); // Speicher freigeben
*/
</code></pre>
<p>Bei deinem zweiten Code löschst du die unique_ptrs, bei denen der Destruktor aufgerufen wurde aus dem Vector raus, deshalb führt es zu keinen Problemen bei der for-Loop.</p>
<p>Dein Code ist allgemein</p>
<p>nwp3 schrieb:</p>
<blockquote>
<p>Ausgesprochen unschön.</p>
</blockquote>
<p>wofür braucht man den so etwas <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2410127</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2410127</guid><dc:creator><![CDATA[waspassiert]]></dc:creator><pubDate>Wed, 23 Jul 2014 17:17:32 GMT</pubDate></item><item><title><![CDATA[Reply to Ist Iterieren über Elemente, die gerade gelöscht werden UB? on Wed, 23 Jul 2014 18:25:21 GMT]]></title><description><![CDATA[<p>waspassiert schrieb:</p>
<blockquote>
<p>wofür braucht man den so etwas <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /></p>
</blockquote>
<p>GUI-Kram. Ich habe eine Art Radio-Button der gelöscht werden kann und wenn er ausgewählt war muss er einen anderen Radio-Button auswählen, damit die Liste keine leere Auswahl hat. Und wenn ein anderes Set von Radio-Buttons ausgewählt wird muss die ganze Liste gelöscht werden und die Buttons schieben sich gegenseitig den &quot;ausgewählt&quot;-Status zu.</p>
<p>Alternativen wären<br />
-ein &quot;Ihr werdet gleich alle gelöscht also wählt keinen Nachfolger&quot;-Flag setzen und abfragen<br />
-manuell den aktiven Button inaktiv setzen, dann wird nichts weitergeschoben<br />
-eine leere Auswahl zulassen<br />
-Proposal für C++17 machen das vorschreibt dass das funktionieren muss und solange warten</p>
<p>Nichts davon sieht sonderlich überzeugend aus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2410137</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2410137</guid><dc:creator><![CDATA[nwp3]]></dc:creator><pubDate>Wed, 23 Jul 2014 18:25:21 GMT</pubDate></item><item><title><![CDATA[Reply to Ist Iterieren über Elemente, die gerade gelöscht werden UB? on Wed, 23 Jul 2014 19:38:13 GMT]]></title><description><![CDATA[<p>RAII in Ehren, aber einen Nachfolger zu bestimmen ist keine Aufgabe für einen Destruktor ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2410153</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2410153</guid><dc:creator><![CDATA[waspassiert]]></dc:creator><pubDate>Wed, 23 Jul 2014 19:38:13 GMT</pubDate></item><item><title><![CDATA[Reply to Ist Iterieren über Elemente, die gerade gelöscht werden UB? on Wed, 23 Jul 2014 20:57:56 GMT]]></title><description><![CDATA[<p>Jemand wird den Button initialisieren und ihm den richtigen Zustand zuweisen. Genau derjenige sollte also ihn wieder löschen. Symmetrie.</p>
<p>Das was du machst ist ein delete-this-Idiom. Sowas führt mittelfristig immer zu Problemen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2410165</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2410165</guid><dc:creator><![CDATA[Zerlöscherer]]></dc:creator><pubDate>Wed, 23 Jul 2014 20:57:56 GMT</pubDate></item><item><title><![CDATA[Reply to Ist Iterieren über Elemente, die gerade gelöscht werden UB? on Wed, 23 Jul 2014 21:10:39 GMT]]></title><description><![CDATA[<p>Zerlöscherer schrieb:</p>
<blockquote>
<p>Jemand wird den Button initialisieren und ihm den richtigen Zustand zuweisen. Genau derjenige sollte also ihn wieder löschen. Symmetrie.</p>
</blockquote>
<p>Habe ich doch. Dieselbe Funktion, die die Buttons in den vector stopft ruft auch vector.clear() auf. Den Zustand bekommen sie im Konstruktor und verlieren ihn im Destruktor, alles schön symmetrisch.</p>
<p>waspassiert schrieb:</p>
<blockquote>
<p>RAII in Ehren, aber einen Nachfolger zu bestimmen ist keine Aufgabe für einen Destruktor ...</p>
</blockquote>
<p>Wahrscheinlich ist das die richtige Lösung. Statt direkt die Buttons zu löschen erst die Auswahl ändern und beim clear eben nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2410166</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2410166</guid><dc:creator><![CDATA[nwp3]]></dc:creator><pubDate>Wed, 23 Jul 2014 21:10:39 GMT</pubDate></item><item><title><![CDATA[Reply to Ist Iterieren über Elemente, die gerade gelöscht werden UB? on Wed, 23 Jul 2014 23:32:12 GMT]]></title><description><![CDATA[<p>Die <code>pop_back</code> Löschen garantiert auch net dass es klappen muss. Auch dabei würde der Destruktor deiner Buttons laufen während eine <code>vector</code> Memberfunktion (nämlich <code>pop_back</code> ) noch ausgeführt wird. Und über den Umweg eines Destruktors auf eine Collection zuzugreifen die gerade modifiziert wird ist UB. Behaupte ich mal. Würde mich SEHR wundern wenn nicht.</p>
<p>Lösung:</p>
<pre><code class="language-cpp">void RemoveLastOne()
{
    unique_ptr&lt;Foo&gt; limbo;
    std::swap(v.back(), limbo);
    v.pop_back();
} // ~Foo läuft jetzt hier, nachdem pop_back fertig gelaufen ist =&gt; jetzt alles OK
</code></pre>
<p>Und wenn du alle löschen willst, dann kannst du natürlich auch gleich</p>
<pre><code class="language-cpp">void RemoveAll()
{
    vector&lt;unique_ptr&lt;Foo&gt;&gt; limbo;
    std::swap(v, limbo);
}
</code></pre>
<p>machen.</p>
<p>Meine GUI Library verwendet aus diesem und ähnlichen Gründen eine eigene &quot;ChildControlCollection&quot;. Die kümmert sich um solche Details, so dass man im Code für die einzelnen Controls bzw. Client Code nicht auf sowas aufpassen muss.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2410174</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2410174</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 23 Jul 2014 23:32:12 GMT</pubDate></item></channel></rss>