Reputation: 181
I can't understand where's the problem with this very simple list I've been testing. The idea is to get the item at position i in a list.
I know usually I wouldn't use a list to do that.
However, this works when I set item = 11
, item = 12
and item = 13
(output would be, respectively, at position {1, 2, 3} there's the item {11, 12, 13}
), BUT it does not work when I set item = 10
, as the output is at position 0 there's the item 6
.
int main(void)
{
list<int> L;
L.push_back(10);
L.push_back(11);
L.push_back(12);
L.push_back(13);
int item = 10;
int pos;
list<int>::iterator it = moveToItem(item, L, pos);
cout << "at position " << pos << " there's the item " << *it;
}
list<int>::iterator moveToItem(int item, list<int> L, int& pos)
{
pos = 0;
list<int>::iterator it = L.begin();
while(*it != item)
{
it++;
pos++;
}
return it;
}
Upvotes: 1
Views: 249
Reputation: 121961
A copy of the list L
is being made when moveToItem()
is called so the returned iterator is referring to an item of a list
that has been destructed. Pass the list
by reference instead:
list<int>::iterator moveToItem(int item, list<int>& L, int& pos)
//^
You should also protect against going past the end()
of the list
in the while
condition, before dereferencing it
.
If this is not an exercise consider using the STL algorithm std::find()
and std::distance()
instead:
#include <iterator>
#include <algorithm>
std::list<int>::iterator it = std::find(L.begin(), L.end(), 41);
if (it != L.end())
{
std::cout << "at position "
<< std::distance(L.begin(), it)
<< " there's the item "
<< *it
<< "\n";
}
Upvotes: 7
Reputation: 45948
You are taking the list by-value. Therefore the returned iterator is an iterator into the local L
argument of the function and is therefore invalid once the function returned (and L
got destroyed). You should take L
by reference:
list<int>::iterator moveToItem(int item, list<int> &L, int& pos)
Performance-wise it's not the best idea to take such a possibly large datastructure as a list by-value, anyway.
Upvotes: 0
Reputation: 11537
You should pass a reference to your list when calling the list<int>::iterator moveToItem(int item, list<int> L, int& pos)
currently a copy of your list made.
So your method should be list<int>::iterator moveToItem(int item, list<int>& L, int& pos)
instead. You can keep the body of your method the same.
Upvotes: 0