{"id":729,"date":"2008-08-27T15:04:35","date_gmt":"2008-08-27T20:04:35","guid":{"rendered":"http:\/\/bobbeaty.com\/wp\/?p=729"},"modified":"2008-08-27T15:04:39","modified_gmt":"2008-08-27T20:04:39","slug":"fun-with-stl-stdmap-iterators-and-erase","status":"publish","type":"post","link":"https:\/\/bobbeaty.com\/wp\/archives\/729","title":{"rendered":"Fun with STL std::map Iterators and <tt>erase()<\/tt>"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bobbeaty.com\/wp\/wp-content\/uploads\/2007\/10\/cplusplus.jpg\" alt=\"cplusplus.jpg\" border=\"0\" width=\"150\" height=\"149\" align=\"right\" \/><\/p>\n<p>Today I got a somewhat sketchy bug report that, if it was true, would <em>possibly<\/em> have pointed to a section in my code where I was deleting things from an STL std::map using the <tt>erase()<\/tt> method whose argument was an iterator on the std::map. The original code looked something like this:<\/p>\n<pre class=\"c\" style=\"font-family:monospace;\">  InstrumentAliasMap<span style=\"color: #339933;\">::<\/span><span style=\"color: #202020;\">iterator<\/span>    ia <span style=\"color: #339933;\">=<\/span> mInstruments.<span style=\"color: #202020;\">begin<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  <span style=\"color: #b1b100;\">while<\/span> <span style=\"color: #009900;\">&#40;<\/span>ia <span style=\"color: #339933;\">!=<\/span> mInstruments.<span style=\"color: #202020;\">end<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n    <span style=\"color: #b1b100;\">if<\/span> <span style=\"color: #009900;\">&#40;<\/span>ia<span style=\"color: #339933;\">-&gt;<\/span>first <span style=\"color: #339933;\">==<\/span> anInstrument<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n      <span style=\"color: #666666; font-style: italic;\">\/\/ found a match - erase it<\/span>\n      mInstruments.<span style=\"color: #202020;\">erase<\/span><span style=\"color: #009900;\">&#40;<\/span>ia<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #009900;\">&#125;<\/span> <span style=\"color: #b1b100;\">else<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n      <span style=\"color: #666666; font-style: italic;\">\/\/ no match, check the next one<\/span>\n      <span style=\"color: #339933;\">++<\/span>ia<span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #009900;\">&#125;<\/span>\n  <span style=\"color: #009900;\">&#125;<\/span><\/pre>\n<p>where my thinking was that the iterator would be updated to the next, valid element after the erase. I think that was a <strong><em>major<\/em><\/strong> boo-boo. In all honesty, I didn't really know, but it <em>seemed<\/em> to test OK, and so it went. The problem is that after the call to <tt>erase()<\/tt> the iterator, <tt>ia<\/tt>, is invalid and can't be moved to the next valid element in the iteration.<\/p>\n<p>I did a little searching on this as I was <strong>sure<\/strong> there was something simple about this. What I read was that the right way to do this was to take advantage of the properties of the post-increment operator which will increment the value (move it to the next element) but return the <em>original<\/em> value. So the code becomes:<\/p>\n<pre class=\"c\" style=\"font-family:monospace;\">  InstrumentAliasMap<span style=\"color: #339933;\">::<\/span><span style=\"color: #202020;\">iterator<\/span>    ia <span style=\"color: #339933;\">=<\/span> mInstruments.<span style=\"color: #202020;\">begin<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  <span style=\"color: #b1b100;\">while<\/span> <span style=\"color: #009900;\">&#40;<\/span>ia <span style=\"color: #339933;\">!=<\/span> mInstruments.<span style=\"color: #202020;\">end<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n    <span style=\"color: #b1b100;\">if<\/span> <span style=\"color: #009900;\">&#40;<\/span>ia<span style=\"color: #339933;\">-&gt;<\/span>first <span style=\"color: #339933;\">==<\/span> anInstrument<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n      <span style=\"color: #666666; font-style: italic;\">\/\/ found a match - erase it<\/span>\n      mInstruments.<span style=\"color: #202020;\">erase<\/span><span style=\"color: #009900;\">&#40;<\/span>ia<span style=\"color: #339933;\">++<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #009900;\">&#125;<\/span> <span style=\"color: #b1b100;\">else<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n      <span style=\"color: #666666; font-style: italic;\">\/\/ no match, check the next one<\/span>\n      <span style=\"color: #339933;\">++<\/span>ia<span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #009900;\">&#125;<\/span>\n  <span style=\"color: #009900;\">&#125;<\/span><\/pre>\n<p>In this code, the iterator is moved to the next valid element and yet the original iterator value is returned to the argument of <tt>erase()<\/tt>. This then removes the element from the map and we're sitting on the next, good one.<\/p>\n<p>I like this a lot more, and it's clear what I <em>should<\/em> have done all along. I won't forget this guy.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today I got a somewhat sketchy bug report that, if it was true, would possibly have pointed to a section in my code where I was deleting things from an STL std::map using the erase() method whose argument was an iterator on the std::map. The original code looked something like this: InstrumentAliasMap::iterator ia = mInstruments.begin&#40;&#41;; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,6],"tags":[],"class_list":["post-729","post","type-post","status-publish","format-standard","hentry","category-coding","category-cube-life"],"_links":{"self":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/729","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/comments?post=729"}],"version-history":[{"count":0,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/729\/revisions"}],"wp:attachment":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/media?parent=729"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/categories?post=729"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/tags?post=729"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}