473,385 Members | 1,356 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Iterator questions...

I've noticed that neither container.begin() nor container.end() return
an error when the container is empty, so I get a nasty segfault when I
dereference the iterator. Do I have to check if the container is
empty every time I use an iterator, or am I missing something?

Speaking of iterators: if I initialize 'iter = container.end()', can I
count on iter to stay equal to container.end() even if elements are
deleted and added to the container?
Jun 27 '08 #1
11 3889
barcaroller wrote:
I've noticed that neither container.begin() nor container.end() return
an error when the container is empty,
Why should they? Empty ranges are perfectly valid and std::sort() will
happily sort an empty range.
so I get a nasty segfault when I dereference the iterator.
Dereferencing an invalid iterator is undefined behavior. You got lucky that
your platform did the right thing and alerted you of the bug.
Do I have to check if the container is
empty every time I use an iterator,
You have to ensure that the iterator is valid before you dereference it. If
you don't know whether the container is empty, you will have to check.
or am I missing something?
No, you seem to be spot on.

Speaking of iterators: if I initialize 'iter = container.end()', can I
count on iter to stay equal to container.end() even if elements are
deleted and added to the container?
That depends on the container: if I recall correctly, only std::list and the
associative containers make that kind of guarantee.
Best

Kai-Uwe Bux
Jun 27 '08 #2
barcaroller wrote:
I've noticed that neither container.begin() nor container.end() return
an error when the container is empty, so I get a nasty segfault when I
dereference the iterator. Do I have to check if the container is
empty every time I use an iterator, or am I missing something?
You are missing something. For an empty containter .begin() == .end()

Aren't you checking to make sure your iteratores aren't equal to .end()?

One of the most common uses of .begin() and .end() is in a for loop, such
as:

std::list<intData;
for ( std::list<int>::iterator it = Data.begin(); it != Data.end(); ++it )
{
// it is guaranteed to be pointing to an item in the list
}

Other uses include passing them to algorithms, also as result of .find()
etc..

But in all cases you must ensure that your iterator != .end()
Speaking of iterators: if I initialize 'iter = container.end()', can I
count on iter to stay equal to container.end() even if elements are
deleted and added to the container?
Hmm.. I'm not sure. I do know that some operations on containers can
invalidate iterators. I'm fairly sure that this includes .end() which
points one past the last item in the container.

--
Jim Langston
ta*******@rocketmail.com
Jun 27 '08 #3
"Jim Langston" <ta*******@rocketmail.comwrites:
barcaroller wrote:
>I've noticed that neither container.begin() nor container.end() return
an error when the container is empty, so I get a nasty segfault when I
dereference the iterator. Do I have to check if the container is
empty every time I use an iterator, or am I missing something?

You are missing something. For an empty containter .begin() == .end()
Even more, .end() is always an invalid iterator that cannot be
derefenced!
[...]
But in all cases you must ensure that your iterator != .end()
>Speaking of iterators: if I initialize 'iter = container.end()', can I
count on iter to stay equal to container.end() even if elements are
deleted and added to the container?

Hmm.. I'm not sure. I do know that some operations on containers can
invalidate iterators. I'm fairly sure that this includes .end() which
points one past the last item in the container.
Yes, the old value of .end() may become valid, which would be invalid,
for an iterator that must always be invalid :-)

--
__Pascal Bourguignon__
Jun 27 '08 #4
barcaroller wrote:
I've noticed that neither container.begin() nor container.end() return
an error when the container is empty, so I get a nasty segfault when I
dereference the iterator. Do I have to check if the container is
empty every time I use an iterator, or am I missing something?
What do you suggest would happen if you dereference the begin()
iterator of an empty container?

You have to check if the iterator equals the end() iterator before
dereferencing it. Dereferencing the end() iterator is invalid.
Jun 27 '08 #5
On May 15, 11:54 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:

One of the most common uses of .begin() and .end() is in a for loop, such
as:

std::list<intData;
for ( std::list<int>::iterator it = Data.begin(); it != Data.end(); ++it )
{
// it is guaranteed to be pointing to an item in the list

}

Actually, I'm not using the iterator in a loop. Briefly, I save the
iterator of the last successful find(). Before I call find() again, I
first check if the last iterator points to the info that I need. If
not, then I
call find(). In essence, I'm caching the iterator to improve
performance, by avoiding a call to find().

Note: where find() is either a member function or an algorithm.

However, caching iterators has its own problems. Initialization,
invalidation, etc.

Jun 27 '08 #6
On May 16, 4:11 am, Juha Nieminen <nos...@thanks.invalidwrote:
What do you suggest would happen if you dereference the begin()
iterator of an empty container?
As I said earlier, I get a segfault. I would expect begin() to return
the iterator equivalent of NULL or throw an exception or something.
If the container is empty, begin() should not return a valid value.
But that's just my opinion.

You have to check if the iterator equals the end() iterator before
dereferencing it. Dereferencing the end() iterator is invalid.
Yes, that's right. Please see my response to Jim.

Jun 27 '08 #7
barcaroller wrote:
On May 15, 11:54 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:

>One of the most common uses of .begin() and .end() is in a for loop,
such as:

std::list<intData;
for ( std::list<int>::iterator it = Data.begin(); it != Data.end();
++it ) {
// it is guaranteed to be pointing to an item in the list

}


Actually, I'm not using the iterator in a loop. Briefly, I save the
iterator of the last successful find(). Before I call find() again, I
first check if the last iterator points to the info that I need. If
not, then I
call find(). In essence, I'm caching the iterator to improve
performance, by avoiding a call to find().

Note: where find() is either a member function or an algorithm.

However, caching iterators has its own problems. Initialization,
invalidation, etc.
..find() can and will return .end() if the item was not found. You need to
test for this and not attempt to dereference the iterator if it is .end().
Also be aware that you are "saving the iterator". Be sure there is no
interventing changes to the vector that can invalidate your reference.
Without seeing your actual code I can not say for certain why the
dereference is not working, only that there is something you are not taking
into account, most likely the iterator pointing to .end() or being
invalidated because of operations on the container.

--
Jim Langston
ta*******@rocketmail.com
Jun 27 '08 #8
barcaroller wrote:
On May 16, 4:11 am, Juha Nieminen <nos...@thanks.invalidwrote:
> What do you suggest would happen if you dereference the begin()
iterator of an empty container?

As I said earlier, I get a segfault. I would expect begin() to return
the iterator equivalent of NULL or throw an exception or something.
If the container is empty, begin() should not return a valid value.
But that's just my opinion.
If the container is empty .begin() will be equal to .end() which is invalid
to be referenced but can be tested against.

In a way, .end() is the iterator equivalent of NULL, as both can not be
dereference and both can be tested against.
> You have to check if the iterator equals the end() iterator before
dereferencing it. Dereferencing the end() iterator is invalid.

Yes, that's right. Please see my response to Jim.


--
Jim Langston
ta*******@rocketmail.com
Jun 27 '08 #9

"Jim Langston" <ta*******@rocketmail.comwrote in message
news:NA**************@newsfe05.lga...
barcaroller wrote:
>I've noticed that neither container.begin() nor container.end() return
an error when the container is empty, so I get a nasty segfault when I
dereference the iterator. Do I have to check if the container is
empty every time I use an iterator, or am I missing something?

You are missing something. For an empty containter .begin() == .end()

Aren't you checking to make sure your iteratores aren't equal to .end()?

One of the most common uses of .begin() and .end() is in a for loop, such
as:

std::list<intData;
for ( std::list<int>::iterator it = Data.begin(); it != Data.end(); ++it )
{
// it is guaranteed to be pointing to an item in the list
}
Actually, I'm not using the iterator in a loop. Briefly, I save the
iterator of the last successful find(). Before I call find() again, I first
check if the last iterator points to the info that I need. If not, then I
call find(). In essence, I'm caching the iterator to improve performance,
by avoiding a call to find().

Note: where find() is either a member function or an algorithm.

However, caching iterators has its own problems. Initialization,
invalidation, etc.
Jun 27 '08 #10
On May 16, 8:10 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
barcaroller wrote:
In a way, .end() is the iterator equivalent of NULL, as both can not be
dereference and both can be tested against.
Indeed, with one exception. Unlike NULL, the value of end() can
change for some containers, making the following code invalid:

// Initialize savedlastIter
savedlastIter = container.end();

// Lots of other code

if (savedLastIter == container.end())
{
// savedLastIter has not been set yet
savedlastIter = container.find(whatIWant);

// could still be end()
}
else
{
// savedlastIter seems to have been set
if (savedlastIter->whatIwant())
// we're done
else
{
savedLastIter= find(whatIWant);

// could still be end()
}
}
This is just pseudo-code; there's lost of safety checks missing but
you get the idea.
Jun 27 '08 #11
On May 15, 7:44 pm, barcaroller <barcarol...@gmail.comwrote:
I've noticed that neither container.begin() nor container.end() return
an error when the container is empty, so I get a nasty segfault when I
dereference the iterator. Do I have to check if the container is
empty every time I use an iterator, or am I missing something?

Speaking of iterators: if I initialize 'iter = container.end()', can I
count on iter to stay equal to container.end() even if elements are
deleted and added to the container?
I apologize for the duplicate messages in this thread. I don't know
why the server is doing this.
Jun 27 '08 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: greg | last post by:
Hello all, I havent used STL containers much, as I am used to MFC containers/classes always ..The differences that I could see is iterators and algorithms. The algorithms providing some basic...
3
by: CoolPint | last post by:
If I were to design my own container and its iterators, I understand that I need to provide both "iterator" and "const_iterator" so that begin() and end() return appropriate ones depending on the...
4
by: matthurne | last post by:
I am working through exercise 8-2 in Accelerated C++...I am implementing the function equal(b, e, b2) where b is an iterator for the first element in a container, e is an iterator pointing to one...
1
by: James Aguilar | last post by:
Hey all, I ran into an interesting little problem with defining an iterator in a custom array class the other day. It goes something like this: template <typename T> class Array { public:...
11
by: Mateusz Loskot | last post by:
Hi, I have a simple question about naming convention, recommeded names or so in following case. I have a class which is implemented with one of STL container (aggregated) and my aim is to...
1
by: flopbucket | last post by:
Hi, For the learning experience, I am building a replacement for std::map. I built a templated red-black tree, etc., and all the basic stuff is working well. I implemented basic iterators and...
5
by: cai_xiaodong | last post by:
I am very new to STL and generic programming. PLEASE help. I have my own class looks like: class pixelProperty { public: // get-functions here... private: Point mPosition; int ...
0
by: toton | last post by:
Hi, I have a complex design of some dynamic situation. First I am posting the design, then a few questions regarding the problem I am facing. Hope some of the experts will answer the questions....
1
by: Scott Gifford | last post by:
Hello, I'm working on an providing an iterator interface to a database. The basic thing I'm trying to accomplish is to have my iterator read rows from the database and return constructed...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.