stl list's const_itertor problem

  • Thread starter Thread starter Abubakar
  • Start date Start date
A

Abubakar

Hi,

I'm using stl's list class. For iterating it I'm using its const_iterator.
Lets say I have a:
list<char* >::const_iterator m_myitr;
Now:
void proc1()
{
if (some_condition_true)
mylist.remove ( m_myitr );
}

void proc2()
{
// here we have to use m_myitr assuming that
// its pointing to a valid data in the list which hasnt been removed
char * tmp = * m_myitr;
}

void useall()
{
// lets initialize m_myitr .....
m_myitr = mylist.begin();
proc1();
proc2();

}

The problem is at proc2(). If m_myitr has been removed in proc1() I'm going
to get an exception here which of course I want to avoid. There should be
some *if* check which is what I'm not able to write cuz I dont know how
iterator class is behaving/working.

Please tell me that *if* condition that i should write before assigning its
value to char * tmp;. so that I know that it was removed or not .

Regards,

-ab.
 
I made a mistake writing the proc1()'s remove method sample code, it should
have been passed as " " * m_myitr " not just "m_myitr".

-ab.
 
I have tried and the following is working:

if ( m_myitr._Mycont == NULL )
this means its been removed;
else
not removed.

I wanna know is this the correct way?

regards,

-ab.
 
Hi,

I would propose:

void proc1()
{
if(some_condition)
{
mylist.remove(m_myitr);
m_myitr = mylist.end();
}
}

void proc2()
{
if(m_myitr != mylist.end())
{
char* tmp = *m_myitr;
}
}

If they are call from multiple threads you must protect m_myitr and mylist
from being changed concurrently.
 
Thanks.

-ab.

SvenC said:
Hi,

I would propose:

void proc1()
{
if(some_condition)
{
mylist.remove(m_myitr);
m_myitr = mylist.end();
}
}

void proc2()
{
if(m_myitr != mylist.end())
{
char* tmp = *m_myitr;
}
}

If they are call from multiple threads you must protect m_myitr and mylist
from being changed concurrently.
 
Abubakar said:
I have tried and the following is working:

if ( m_myitr._Mycont == NULL )
this means its been removed;
else
not removed.

I wanna know is this the correct way?

Well, it's correct in that I think it works on one specific
implementation with one specific set of compiler/library options. It's
incorrect in that it won't work anywhere else, and is non-standard.
Avoid using anything starting with a _ and a capital letter or
containing a double underscore, unless you have read any documentation
relating to it (there usually won't be any) and accept the extreme
limitations (usually that your code will not port to any other compiler,
including often the next version of the one you are using).

Setting an iterator to cont.end() and checking for that is the most
acceptable way of creating a "null" iterator. If you don't have a
specific container to use that you can guarantee will stay live as long
as m_myitr will, you'll need a second variable, bool m_ismyitrOk or similar.

Tom
 
Abubakar a écrit :
I have tried and the following is working:

if ( m_myitr._Mycont == NULL )
this means its been removed;
else
not removed.

I wanna know is this the correct way?

NO! You are relying on the internal implementation details of the list
iterator (everythng that begins with "_" + Uppercase or "__" is an
implementation detail of the CRT).

It will not work on another computer, and it may not work on next
version of VC.

The rule is that a list iterator is invalidated when the element it
points to is removed from the list (baware that this is the rule for
list : rules for other containers are different).

Using an invalid iterator is Undefined Behaviour (UB), so there is no
way to detect wether an iterator is valid or not - think of it as
dereferencing a pointer you've just called delete upon.
Therefore, you need to track in your algorithms when an iterator is
valid or not. You've already been given an example.

Arnaud
MVP - VC
 
Thanks guys. Arnaud & Tom.

regards,

-ab.


Abubakar a écrit :
I have tried and the following is working:

if ( m_myitr._Mycont == NULL )
this means its been removed;
else
not removed.

I wanna know is this the correct way?

NO! You are relying on the internal implementation details of the list
iterator (everythng that begins with "_" + Uppercase or "__" is an
implementation detail of the CRT).

It will not work on another computer, and it may not work on next
version of VC.

The rule is that a list iterator is invalidated when the element it
points to is removed from the list (baware that this is the rule for
list : rules for other containers are different).

Using an invalid iterator is Undefined Behaviour (UB), so there is no
way to detect wether an iterator is valid or not - think of it as
dereferencing a pointer you've just called delete upon.
Therefore, you need to track in your algorithms when an iterator is
valid or not. You've already been given an example.

Arnaud
MVP - VC
 
Back
Top