TinyTiger
TinyTiger

Reputation: 2053

Why does my for loop throw an "out_of_range" error?

I am learning c++ and for a test problem I am using a for loop with condition prices.size()-1 so the vector does not go out of range.

std::vector<int> prices {7,1,5,3,6,4};

int maxProfit(vector<int>& prices) {
    int total {0};
    for (size_t i = 0; i < prices.size()-1; i++) {
        if (prices.at(i+1) > prices.at(i)) {
            total += prices.at(i+1) - prices.at(i);
        }
    }
    return total;
}

But it is throwing this this runtime error that I cannot decipher:

terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 1) >= this->size() (which is 0)

I cannot figure out the problem, can someone please show me what I am doing wrong.

Upvotes: 0

Views: 354

Answers (1)

Sam Varshavchik
Sam Varshavchik

Reputation: 118292

Look at the error message carefully:

this->size() (which is 0)

The error message indicates that the passed-in vector is empty. Its size() is 0. Now take a closer look at the for-loop:

for (size_t i = 0; i < prices.size()-1; i++)

We've established that prices.size() is 0, so this becomes, effectively:

for (size_t i = 0; i < -1; i++)

But i is a size_t, which is an unsigned type, so -1 gets casted to an unsigned type.

Now, perform a little experiment yourself, see what output you get from the following statement:

std::cout << (size_t)-1 << std::endl;

Because of this, even though the vector is empty, the for loop's condition will still evaluate to true, and inside the for loop the code will attempt to access a non-existent array value, hence the exception.

Note that the function's parameter of prices has nothing to do with the global prices vector. The code from your program that you did not show passes in an empty vector, resulting in this error. Why the vector that gets passed in is empty, this is something you will need to figure out on your own.

Note that it's fairly easy to tweak the for-loop, just slightly, so that this edge case gets correctly handled. Simply change the for loop's condition as follows:

for (size_t i = 0; i+1 < prices.size(); i++)

Even though this seems to be the same thing, it's not (at least until you manage to create an array with about four billion, or so, values -- more on a 64 bit platform). Welcome to C++.

Upvotes: 5

Related Questions