0

Can some one shed some light on why this code snipit will run though the loop once but then give an assertion failure Expression: vector iterator not decrementable?

for (auto an = a.rbegin(); an != a.rend(); ++an, indexA--) //first number 
{
        for (auto bn = b.rbegin(); bn != b.rend(); ++bn) //second number
        {
            if (*an - *bn >= 0)
            {
                returnVal.push_back(*an - *bn);
                a.pop_back();
                b.pop_back();
            }
            else
            {
                brrow = *an + 10;
                a.at(indexA - 1) = a.at(indexA - 1) - 1; // remove 1 from the spot ahead of current digit
                returnVal.push_back(brrow - *bn);
                a.pop_back();
                b.pop_back();
            }
        }   
}
Lupus
  • 49
  • 6

2 Answers2

1

Based on your comments, it seems you want to move through both iterator ranges in tandem - that only needs one for loop, like this:

auto an = a.rbegin();
for (auto bn = b.rbegin();
     an != a.rend() && bn != b.rend();
     ++an, ++bn, indexA--)
    if (*an - *bn >= 0)
        returnVal.push_back(*an - *bn);
    else
    {
        brrow = *an + 10;
        --(a.at(indexA - 1)); // remove 1 from the spot ahead of current digit
                              // shouldn't you check for rend() first????
        returnVal.push_back(brrow - *bn);
    }

Note that both iterators can be declared as for-loop local if you know they'll be of the exact same type:

for (auto an = a.rbegin(), bn = b.rbegin(); ...
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • Thanks, I have been trying to rack my head for a O(n) solution for a bit. for some reason my mind got stuck on "I have 2 vectors I need 2 loops" This does get rid of the errors that I have. – Lupus Mar 24 '15 at 05:56
0

pop_back() will make your iterator invalid.

Following explains more in detail (Does pop_back() really invalidate *all* iterators on an std::vector?):

Here is your answer, directly from The Holy Standard:

23.2.4.2 A vector satisfies all of the requirements of a container and of a reversible container (given in two tables in 23.1) and of a sequence, including most of the optional sequence requirements (23.1.1).

23.1.1.12 Table 68 expressiona.pop_back() return typevoid operational semanticsa.erase(--a.end()) containervector, list, deque

Notice that a.pop_back is equivalent to a.erase(--a.end()). Looking at vector's specifics on erase:

23.2.4.3.3 - iterator erase(iterator position) - effects - Invalidates all the iterators and references after the point of the erase

Therefore, once you call pop_back, any iterators to the previously final element (which now no longer exists) are invalidated.


More information: FAQ "Iterator invalidation rules": Iterator invalidation rules

Community
  • 1
  • 1
jaguzu
  • 528
  • 5
  • 14