Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. Clever Code
  4. they say map::insert doesn't change iterators [modified]

they say map::insert doesn't change iterators [modified]

Scheduled Pinned Locked Moved Clever Code
c++comtoolsquestion
3 Posts 2 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    peterchen
    wrote on last edited by
    #1

    (and they are right, technically) I have a map[int /*id*/, somedata], which has a method

    Map::MoveRangeTo(int targetID, Map & targetMap, int firstID, int lastID)
    {
    // some pseudocode:
    if (this == &target) // check that ranges don't overlap
    ASSERT(targetIDlastID);

    Map::iterator it startAt, endAt;
    GetRange(startAt, endAt, firstID, lastID);
    // this returns the STL range with all values in [first, last].
    // GetRange works correctly.

    for(iterator it = startAt; it != endAt; ++it)
    {
    targetMap[it->first + targetID-firstID] = it->second; // flat copy
    it->second = null; // ..and set as "unused" in source
    }
    erase(startAt, endAt); // remove all null values from source map
    }

    I thought there can't be problems with IDs changing due to the insert operation in the target. Yet apaprently, there is a case where the loop doesn't terminate. Hint1: targetMap=sourceMap Hint2: STL ranges are iterator to first, and iterator behind last -- modified at 7:12 Thursday 7th December, 2006


    Developers, Developers, Developers, Developers, Developers, Developers, Velopers, Develprs, Developers!
    We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
    Linkify!|Fold With Us!

    T 1 Reply Last reply
    0
    • P peterchen

      (and they are right, technically) I have a map[int /*id*/, somedata], which has a method

      Map::MoveRangeTo(int targetID, Map & targetMap, int firstID, int lastID)
      {
      // some pseudocode:
      if (this == &target) // check that ranges don't overlap
      ASSERT(targetIDlastID);

      Map::iterator it startAt, endAt;
      GetRange(startAt, endAt, firstID, lastID);
      // this returns the STL range with all values in [first, last].
      // GetRange works correctly.

      for(iterator it = startAt; it != endAt; ++it)
      {
      targetMap[it->first + targetID-firstID] = it->second; // flat copy
      it->second = null; // ..and set as "unused" in source
      }
      erase(startAt, endAt); // remove all null values from source map
      }

      I thought there can't be problems with IDs changing due to the insert operation in the target. Yet apaprently, there is a case where the loop doesn't terminate. Hint1: targetMap=sourceMap Hint2: STL ranges are iterator to first, and iterator behind last -- modified at 7:12 Thursday 7th December, 2006


      Developers, Developers, Developers, Developers, Developers, Developers, Velopers, Develprs, Developers!
      We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
      Linkify!|Fold With Us!

      T Offline
      T Offline
      Todd Smith
      wrote on last edited by
      #2

      Not sure about the map issue yet but this is iffy: if (this == &target) // check that ranges don't overlap ASSERT(targetIDlastID); what if someone uses this code in an environment where ASSERT goes away in release mode?

      Todd Smith

      P 1 Reply Last reply
      0
      • T Todd Smith

        Not sure about the map issue yet but this is iffy: if (this == &target) // check that ranges don't overlap ASSERT(targetIDlastID); what if someone uses this code in an environment where ASSERT goes away in release mode?

        Todd Smith

        P Offline
        P Offline
        peterchen
        wrote on last edited by
        #3

        The check is implicit in the caller, I just put it there to note that I though of overlapping. At least I thought I thought of it :cool: The problem is: endAt points to one after the last one to copy (id=149), and for specific target IDs, the item get moved to before endAt. (you are right, though. For a publicly exposed method there should be a runtime check, as it is cheap)


        Developers, Developers, Developers, Developers, Developers, Developers, Velopers, Develprs, Developers!
        We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
        Linkify!|Fold With Us!

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups