Mars
Mars

Reputation: 4995

Incrementing iterator and passing the argument in a recursion loop

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

Answers (3)

user529758
user529758

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

LarryPel
LarryPel

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

Jarod42
Jarod42

Reputation: 217880

  • *vec.end() is incorrect.
  • What is the purpose of the return value ?
  • You should use reference to avoid to copy vector each time.
  • Add some constness.

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

Related Questions