<?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[Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird?]]></title><description><![CDATA[<p>Heyho,</p>
<p>ich hab momentan folgendes Problem:</p>
<p>Ich habe zwei Maps. Ich möchte jeden Eintrag in der einen Map löschen, wenn ein Eintrag mit dem selben Key in der anderen Map vorhanden ist. Dazu gehe ich in einer Schleife durch alle Einträge der ersten Map und suche nach einen Eintrag in der zweiten Map, der den selben Key hat.<br />
Hier mal ein Bsp:</p>
<pre><code class="language-cpp">#include &lt;map&gt;
using namespace std;

int main()
{
   map&lt;int, int&gt; erste;
   map&lt;int, int&gt; zweite;

   ...

   map&lt;int, int&gt; :: iterator iter;
   iter = erste.begin();
   while (iter != erste.end())
   {
      map&lt;int, int&gt; :: iterator iter2;
      iter2 = zweite.find(iter-&gt;first);
      if (iter2 != zweite.end()
      {
         erste.erase(iter);             // hier liegt das Problem
      }
      iter++;
   }
   return 0;
}
</code></pre>
<p>Nun war ich mir nicht sicher, wohin der Iterator iter zeigt, wenn der Eintrag, auf den er eigentlich zeigt, gelöscht wird.<br />
Darauf hin hab ich nen Kollegen gefragt, er meinte, dass iter mit dem Löschen des Eintrages ungültig wird. Das selbe hab ich auch in einem englischen Forum gefunden.</p>
<p>Also umgehe ich das Problem momentan folgender Maßen:</p>
<pre><code class="language-cpp">#include &lt;map&gt;
using namespace std;

int main()
{
   map&lt;int, int&gt; erste;
   map&lt;int, int&gt; zweite;

   ...

   map&lt;int, int&gt; :: iterator iter;
   iter = erste.begin();
   while (iter != erste.end())
   {
      map&lt;int, int&gt; :: iterator iter2;
      iter2 = zweite.find(iter-&gt;first);
      if (iter2 != zweite.end()
      {
         map&lt;int, int&gt; :: iterator iter3;
         iter--;
         iter3 = iter;
         iter++;
         erste.erase(iter);
         iter = iter3; 
      }
      iter++;
   }
   return 0;
}
</code></pre>
<p>Somit habe ich nach dem Löschen wieder ein Iterator auf dem vorgänger Element, welcher dann automatisch auf das nächste Element incrementiert wird.<br />
Allerdings finde ich diese Lösung absolut unschön (von den Variablennamen mal abgesehen). Habt ihr ne elegantere Möglichkeit dieses Problem zu umgehen?</p>
<p>Gruß K3il3</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/200414/verhalten-eines-iterators-wenn-der-eintrag-auf-den-er-zeigt-aus-der-stl-map-gelöscht-wird</link><generator>RSS for Node</generator><lastBuildDate>Sun, 04 Oct 2026 19:51:57 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/200414.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 14 Dec 2007 13:47:33 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Fri, 14 Dec 2007 14:20:21 GMT]]></title><description><![CDATA[<p>Heyho,</p>
<p>ich hab momentan folgendes Problem:</p>
<p>Ich habe zwei Maps. Ich möchte jeden Eintrag in der einen Map löschen, wenn ein Eintrag mit dem selben Key in der anderen Map vorhanden ist. Dazu gehe ich in einer Schleife durch alle Einträge der ersten Map und suche nach einen Eintrag in der zweiten Map, der den selben Key hat.<br />
Hier mal ein Bsp:</p>
<pre><code class="language-cpp">#include &lt;map&gt;
using namespace std;

int main()
{
   map&lt;int, int&gt; erste;
   map&lt;int, int&gt; zweite;

   ...

   map&lt;int, int&gt; :: iterator iter;
   iter = erste.begin();
   while (iter != erste.end())
   {
      map&lt;int, int&gt; :: iterator iter2;
      iter2 = zweite.find(iter-&gt;first);
      if (iter2 != zweite.end()
      {
         erste.erase(iter);             // hier liegt das Problem
      }
      iter++;
   }
   return 0;
}
</code></pre>
<p>Nun war ich mir nicht sicher, wohin der Iterator iter zeigt, wenn der Eintrag, auf den er eigentlich zeigt, gelöscht wird.<br />
Darauf hin hab ich nen Kollegen gefragt, er meinte, dass iter mit dem Löschen des Eintrages ungültig wird. Das selbe hab ich auch in einem englischen Forum gefunden.</p>
<p>Also umgehe ich das Problem momentan folgender Maßen:</p>
<pre><code class="language-cpp">#include &lt;map&gt;
using namespace std;

int main()
{
   map&lt;int, int&gt; erste;
   map&lt;int, int&gt; zweite;

   ...

   map&lt;int, int&gt; :: iterator iter;
   iter = erste.begin();
   while (iter != erste.end())
   {
      map&lt;int, int&gt; :: iterator iter2;
      iter2 = zweite.find(iter-&gt;first);
      if (iter2 != zweite.end()
      {
         map&lt;int, int&gt; :: iterator iter3;
         iter--;
         iter3 = iter;
         iter++;
         erste.erase(iter);
         iter = iter3; 
      }
      iter++;
   }
   return 0;
}
</code></pre>
<p>Somit habe ich nach dem Löschen wieder ein Iterator auf dem vorgänger Element, welcher dann automatisch auf das nächste Element incrementiert wird.<br />
Allerdings finde ich diese Lösung absolut unschön (von den Variablennamen mal abgesehen). Habt ihr ne elegantere Möglichkeit dieses Problem zu umgehen?</p>
<p>Gruß K3il3</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420544</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420544</guid><dc:creator><![CDATA[K3il3]]></dc:creator><pubDate>Fri, 14 Dec 2007 14:20:21 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Fri, 14 Dec 2007 14:03:18 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">map&lt;int, int&gt; :: iterator iter;
   iter = erste.begin();
   while (iter != erste.end())
   {
      map&lt;int, int&gt; :: iterator iter2 = zweite.find(iter-&gt;first);
      if (iter2 != zweite.end()
         iter = erste.erease(iter);
      else
         iter++;
   }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1420552</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420552</guid><dc:creator><![CDATA[das mobvieh]]></dc:creator><pubDate>Fri, 14 Dec 2007 14:03:18 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Fri, 14 Dec 2007 14:21:03 GMT]]></title><description><![CDATA[<p>hmm,</p>
<p>laut dieser Referenz ist die Funktion erase() der Map eine void Funktion, somit wird doch kein neuer Iterator zurückgegeben?</p>
<p><a href="http://www.sgi.com/tech/stl/Map.html" rel="nofollow">http://www.sgi.com/tech/stl/Map.html</a></p>
<p>In dieser Referenz steht auch, dass erase() ne void Funktion ist. Glaube also nicht, dass deine Lösung funktioniert.</p>
<p><a href="http://www.cppreference.com/cppmap/erase.html" rel="nofollow">http://www.cppreference.com/cppmap/erase.html</a></p>
<p>Bitte nur Lösungen anbieten von denen man weiss, dass sie funktionieren! Und wenn möglich, noch ein kleinen Kommentar zu der Lösung geben. Danke</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420555</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420555</guid><dc:creator><![CDATA[K3il3]]></dc:creator><pubDate>Fri, 14 Dec 2007 14:21:03 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Fri, 14 Dec 2007 14:40:22 GMT]]></title><description><![CDATA[<p>K3il3 schrieb:</p>
<blockquote>
<p>In dieser Referenz steht auch, dass erase() ne void Funktion ist. Glaube also nicht, dass deine Lösung funktioniert.</p>
</blockquote>
<p>ok, hab ich mit der intuitiven lösung wohl daneben gelegen.</p>
<blockquote>
<p>Bitte nur Lösungen anbieten von denen man weiss, dass sie funktionieren! Und wenn möglich, noch ein kleinen Kommentar zu der Lösung geben. Danke</p>
</blockquote>
<p>vielen dank für die belehrung. wird nicht wieder vorkommen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420577</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420577</guid><dc:creator><![CDATA[das mobvieh]]></dc:creator><pubDate>Fri, 14 Dec 2007 14:40:22 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Fri, 14 Dec 2007 15:15:39 GMT]]></title><description><![CDATA[<p>warum durchläufst du nicht die zweite map und löscht alles in der ersten, was du dort findest?</p>
<pre><code class="language-cpp">for (map&lt;int,int&gt;::iterator i = zweite.begin(); i != zweite.end(); ++i)
{
  erste.erase(i-&gt;first);
}
</code></pre>
<p>andernfalls sei noch gesagt, dass erase bei maps nur den aktuellen iterator invalidiert, alle anderen aber unberührt lassen muss. d.h. du brauchst eine kopie des iterators, bevor du ihn inkrementierst. in C++ gibt es dafür sogar einen eigenen operator:</p>
<pre><code class="language-cpp">if (iter2 != zweite.end())
{
 erste.erase(iter++); //erstelle eine kopie von iter (die wird invalidiert) und 
//bevor sie invalidiert wird, zeigt iter schon auf das nächste element.
} else ++iter;
</code></pre>
<p>PS. nicht nur eine stilfrage: initialisiere deine iteratoren gleich gleich bei ihrer definition (RAII):</p>
<pre><code class="language-cpp">map&lt;int,int&gt;::iterator i = erste.find(...)
</code></pre>
<p>macht den code auch übersichtlicher.</p>
<p>@das mobvieh: du hast einfach assoziative container mit sequenzcontainern verwechselt, bei denen funktioniert erase nämlich so.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420588</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420588</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Fri, 14 Dec 2007 15:15:39 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Fri, 14 Dec 2007 15:20:49 GMT]]></title><description><![CDATA[<p>Danke für die Lösung.<br />
Man muss bei der 2. Variante allerdings aufpassen, dass man den iter in der Schleife nicht noch mal incrementiert, ohne abzusichern dass er durch dein increment nicht bei erste.end() steht. Ansonsten kann es zu bösen Fehlern kommen.</p>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420603</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420603</guid><dc:creator><![CDATA[K3il3]]></dc:creator><pubDate>Fri, 14 Dec 2007 15:20:49 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Fri, 14 Dec 2007 15:15:21 GMT]]></title><description><![CDATA[<p>K3il3 schrieb:</p>
<blockquote>
<p>Danke für die Lösung.<br />
Man muss bei der 2. Variante allerdings aufpassen, dass man den iter in der Schleife nicht noch mal incrementiert, ohne abzusichern dass er durch dein increment nicht bei erste.end() steht. Ansonsten kann es zu bösen Fehlern kommen.</p>
<p>Gruß</p>
</blockquote>
<p>ja. die inkrementierung aus der schleife raus, für die wird in dem if/else block gesorgt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420605</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420605</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Fri, 14 Dec 2007 15:15:21 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Fri, 14 Dec 2007 15:26:20 GMT]]></title><description><![CDATA[<p>ja schon, aber es kann ja immernoch vorkommen, dass man an einer anderen stelle in der schleife incrementiert.</p>
<p>z.b.</p>
<pre><code class="language-cpp">#include &lt;map&gt;
using namespace std;

int main()
{
   map&lt;int, int&gt; erste;
   map&lt;int, int&gt; zweite;

   ...

   map&lt;int, int&gt; :: iterator iter;
   iter = erste.begin();
   while (iter != erste.end())
   {
      map&lt;int, int&gt; :: iterator iter2;
      iter2 = zweite.find(iter-&gt;first);
      if (iter2 != zweite.end()
      {
         erste.erase(iter++);             
      }else iter++;

      ... 

      &lt;tu das&gt;
      &lt;tu jenes&gt;

      ...

      iter++;
   }
   return 0;
}
</code></pre>
<p>Wenn dann der Schleifenkopf das iter wieder mit erste.end() vergleichen will, wird es höchst wahrscheinlich krachen.</p>
<p>Somit bleibt immer ein Restrisiko. Man muss sich also ganz genau überlegen, ob man diese Lösung anwendet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420610</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420610</guid><dc:creator><![CDATA[K3il3]]></dc:creator><pubDate>Fri, 14 Dec 2007 15:26:20 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Fri, 14 Dec 2007 16:30:12 GMT]]></title><description><![CDATA[<p>Pro Schleife darfst du natürlich nur genau 1x den Iterator inkrementieren (aber dies gilt ja für jede Schleife).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420641</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420641</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Fri, 14 Dec 2007 16:30:12 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Fri, 14 Dec 2007 17:12:45 GMT]]></title><description><![CDATA[<p>Da maps wunderbar sortiert sind kann man doch gleich stl-algorithmen verwenden:</p>
<pre><code class="language-cpp">int main() {
  std::map&lt;int, int&gt; erste;
  std::map&lt;int, int&gt; zweite;

  std::map&lt;int, int&gt; tmp(erste); //kopie von erste
  std::map&lt;int,int&gt;::iterator last_of_sequence = 
    std::set_difference(erste.begin(), erste.end(), zweite.begin(), zweite.end(), tmp.begin(), erste.value_comp()); //kopiert alle Werte aus erste, die nich in zweite enthalten sind, an den Anfang von tmp
  tmp.erase(last_of_sequence, tmp.end()); //lösche den rest von tmp
  erste.swap(tmp); //vertausche den inhalt von tmp und erste - erste enhält jetzt nurnoch das was nicht in zweite drin war.
}
</code></pre>
<p>oder noch einfacher:</p>
<pre><code class="language-cpp">int main() {
  std::map&lt;int, int&gt; erste;
  std::map&lt;int, int&gt; zweite;
  std::map&lt;int,int&gt;::iterator last_of_sequence = 
    std::set_difference(erste.begin(), erste.end(), zweite.begin(), zweite.end(), erste.begin(), erste.value_comp());
  erste.erase(last_of_sequence, erste.end());
}
</code></pre>
<p>Bin aber nicht sicher ob das vom Standard garantiert ist, das set_difference entsprechend sicher arbeitet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420660</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420660</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Fri, 14 Dec 2007 17:12:45 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Sat, 15 Dec 2007 00:38:02 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Da maps wunderbar sortiert sind kann man doch gleich stl-algorithmen verwenden:</p>
<pre><code class="language-cpp">int main() {
  std::map&lt;int, int&gt; erste;
  std::map&lt;int, int&gt; zweite;

  std::map&lt;int, int&gt; tmp(erste); //kopie von erste
  std::map&lt;int,int&gt;::iterator last_of_sequence = 
    std::set_difference(erste.begin(), erste.end(), zweite.begin(), zweite.end(), tmp.begin(), erste.value_comp()); //kopiert alle Werte aus erste, die nich in zweite enthalten sind, an den Anfang von tmp
  tmp.erase(last_of_sequence, tmp.end()); //lösche den rest von tmp
  erste.swap(tmp); //vertausche den inhalt von tmp und erste - erste enhält jetzt nurnoch das was nicht in zweite drin war.
}
</code></pre>
<p>oder noch einfacher:</p>
<pre><code class="language-cpp">int main() {
  std::map&lt;int, int&gt; erste;
  std::map&lt;int, int&gt; zweite;
  std::map&lt;int,int&gt;::iterator last_of_sequence = 
    std::set_difference(erste.begin(), erste.end(), zweite.begin(), zweite.end(), erste.begin(), erste.value_comp());
  erste.erase(last_of_sequence, erste.end());
}
</code></pre>
<p>map sortiert allerdings selbst.<br />
Bin aber nicht sicher ob das vom Standard garantiert ist, das set_difference entsprechend sicher arbeitet.</p>
</blockquote>
<p>ich bin immer noch nicht sicher, warum mein erster lösungsvorschlag auf soviel skepsis stößt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420843</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420843</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Sat, 15 Dec 2007 00:38:02 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Sat, 15 Dec 2007 13:55:33 GMT]]></title><description><![CDATA[<p>queer_boy schrieb:</p>
<blockquote>
<p>ich bin immer noch nicht sicher, warum mein erster lösungsvorschlag auf soviel skepsis stößt.</p>
</blockquote>
<p>Skepsis nicht. dein Vorschlag funktioniert wunderbar, ich hab nur eine Alternative aufgezeigt. Welche von beiden performanter ist, hängt vermutlich von der Größe der beiden Maps und der zu löschenden Schnittmenge ab.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1420956</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1420956</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Sat, 15 Dec 2007 13:55:33 GMT</pubDate></item><item><title><![CDATA[Reply to Verhalten eines Iterators, wenn der Eintrag auf den er Zeigt, aus der STL Map gelöscht wird? on Sat, 15 Dec 2007 17:00:05 GMT]]></title><description><![CDATA[<p>sorry, das war auch in richtung des OPs gemeint: er sollte doch einen hinweis genau darauf geben, was du angesprochen hast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1421040</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1421040</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Sat, 15 Dec 2007 17:00:05 GMT</pubDate></item></channel></rss>