Dvole
Dvole

Reputation: 5795

Iterator going outside bounds despite check in C++

I have a function that reverses words in a string, e.g. "hi there Sam" it will reverse a string to "Sam there hi".
It does that by reversing a string, and then reversing words.
But after it's done I get a seg fault on the line with for.
I suspect that iterator tries to dereference outside valid range.
But it is checking for the range first, so if that is invalid, it will immediately drop out.
Where am I wrong?

void rev(string& str) {
    std::reverse(str.begin(), str.end());
    auto bIter = str.begin();
    auto eIter = str.begin();

    while (eIter != str.end()) {
        for (;eIter != str.end() && (*eIter) != ' '; eIter++) {}
        std::reverse(bIter, eIter);
        bIter = ++eIter;
    }
}

Upvotes: 0

Views: 178

Answers (2)

Jarod42
Jarod42

Reputation: 217235

Your problem is that your increase eIter even if it is str.end().

As you already use std, you might transform your loop by std::find:

void rev(std::string& str) {
    std::reverse(str.begin(), str.end());

    for (auto it = str.begin(); it != str.end(); ) {
        auto endWordIt = std::find(it, str.end(), ' ');
        std::reverse(it, endWordIt);
        it = (endWordIt == str.end()) ? str.end() : (endWordIt + 1);
    }
}

Upvotes: 0

set0gut1
set0gut1

Reputation: 1672

When eIter == str.end() at the end of inner for loop, it goes beyond str.end() because of the last line of while loop (++eIter).

Add break solves this issue.

void rev(string& str) {
    std::reverse(str.begin(), str.end());
    auto bIter = str.begin();
    auto eIter = str.begin();

    while (eIter != str.end()) {
        for (;eIter != str.end() && (*eIter) != ' '; eIter++) {}
        std::reverse(bIter, eIter);
        if (eIter == str.end()) break; // HERE
        bIter = ++eIter;
    }
}

Upvotes: 6

Related Questions