Reputation: 4995
I want to print out the values of a vector using a recursive function.
void pvec(int cnt, std::vector<int> vec) {
if(cnt < vec.size()) {
std::cout << vec[cnt++] << std::endl;
return pvec(cnt,vec);
}
}
Instead of using vector subscript I wanted to use iterators. However, when I write up a similar function where I pass an iterator for the first argument and try to return the function with an incremented iterator the loop doesn't stop and I get a segmentation fault. Why is this?
void pvec(std::vector<int>::iterator po, std::vector<int> vec)
{
if(po < vec.end()) {
std::cout << *po++ << std::endl;
return pvec(po,vec);
}
}
I did try making po a reference and this didn't work either.
Upvotes: 2
Views: 2036
Reputation:
I get a segmentation fault. Why is this?
Because your code invokes undefined behavior.
return *(vec.end());
is illegal, since vec.end()
"points" one past the last element. It does not point to the last element. Perhaps you meant
return vec.end()[-1];
instead? If so, you need to check if the vector is empty before accessing the last element.
Upvotes: 3
Reputation: 296
Your problem is that the "vec" argument is passed by copy, so each call of the recursive function will result in a new vector object and comparing iterators of different vectors is simply wrong. That's why your comparison "po < vec.end()" and the recursion never ends.
Also, I don't understand the purpose of returning a value. You should fix the second argument to pass by constant reference and don't return anything:
void pvec(std::vector<int>::iterator po, const std::vector<int>& vec)
{
if(po < vec.end()) {
std::cout << *po++ << std::endl;
pvec(po,vec);
}
}
Upvotes: 1
Reputation: 217880
Fixed version:
void pvec(std::vector<int>::const_iterator po, const std::vector<int>& vec)
{
if(po != vec.end()) {
std::cout << *po++ << std::endl;
pvec(po, vec);
}
}
The crash come from *vec.end() The "strange loop behaviour" come from the comparison of iterators from different vectors (as the vector is copied each time).
Upvotes: 4