does STL hash_multiset erase invalidate the iterator?

Discussion in 'C++' started by Kenneth Massey, Jul 21, 2004.

  1. Is the following code guaranteed to work? I have a hashed set of pointers,
    which I would like to selectively delete from. Can I iterate through the
    set, deleting certain ones, without invalidating the iterator? This
    ominous statement in the STL "set" documentation makes me worried. I saw
    no similar statement on the "hash_multiset" docs.

    "Erasing an element from a set also does not invalidate any iterators,
    except, of course, for iterators that actually point to the element that is
    being erased."



    hash_multiset<mytype*> myset;
    // insert a bunch of mytype pointers into myset

    for (hash_multiset<mytype*>::iterator i=myset.begin(); i!=myset.end(); i++)
    if (mytype->someproperty() == 1) {
    mytype* p = *i;
    myset.erase(i);
    delete p;
    }


    Thanks.
     
    Kenneth Massey, Jul 21, 2004
    #1
    1. Advertising

  2. "Kenneth Massey" <> wrote in message
    news:2gwLc.4988$_K2.2563@lakeread02...
    > Is the following code guaranteed to work? I have a hashed set of

    pointers,
    > which I would like to selectively delete from. Can I iterate through the
    > set, deleting certain ones, without invalidating the iterator? This
    > ominous statement in the STL "set" documentation makes me worried. I saw
    > no similar statement on the "hash_multiset" docs.
    >
    > "Erasing an element from a set also does not invalidate any iterators,
    > except, of course, for iterators that actually point to the element that

    is
    > being erased."
    >
    >
    >
    > hash_multiset<mytype*> myset;
    > // insert a bunch of mytype pointers into myset
    >
    > for (hash_multiset<mytype*>::iterator i=myset.begin(); i!=myset.end();

    i++)
    > if (mytype->someproperty() == 1) {
    > mytype* p = *i;
    > myset.erase(i);
    > delete p;
    > }
    >


    Well you ARE invalidating the iterator, because it does point to the element
    being erased. You erase i and then you do i++, that is using an invalidated
    iterator.

    Here's how to do it

    hash_multiset<mytype*>::iterator i=myset.begin();
    while (i!=myset.end())
    {
    if (mytype->someproperty() == 1)
    {
    mytype* p = *i;
    myset.erase(i++);
    delete p;
    }
    else
    {
    ++i;
    }
    }

    By saying 'myset.erase(i++);' you make sure that the iterator is incremented
    before you erase not afterwards.

    john
     
    John Harrison, Jul 21, 2004
    #2
    1. Advertising

  3. > mytype* p = *i;
    > myset.erase(i++);
    > delete p;


    Incidentally there is no need for the variable p.

    delete *i;
    myset.erase(i++);

    john
     
    John Harrison, Jul 21, 2004
    #3
  4. John Harrison wrote:

    >> mytype* p = *i;
    >> myset.erase(i++);
    >> delete p;

    >
    > Incidentally there is no need for the variable p.
    >
    > delete *i;
    > myset.erase(i++);
    >
    > john


    Thanks for the help.
    Actually I want to make sure the pointer is deleted *after* the set entry
    has been erased. My hash and equal functions reference the pointer through
    ->, and I don't want to risk them being called on a deleted pointer.
     
    Kenneth Massey, Jul 21, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nick Keighley
    Replies:
    4
    Views:
    746
    Carlos Martinez Garcia
    Jan 23, 2006
  2. Varun  Kacholia
    Replies:
    1
    Views:
    317
    Pete Becker
    Apr 1, 2006
  3. Pallav singh
    Replies:
    2
    Views:
    426
    Pallav singh
    Mar 15, 2009
  4. Öö Tiib
    Replies:
    0
    Views:
    738
    Öö Tiib
    Jun 16, 2010
  5. K. Frank
    Replies:
    3
    Views:
    480
    K. Frank
    May 31, 2013
Loading...

Share This Page