Search code examples
c++iteratorc++17indexoutofboundsexceptionstdvector

Iterator bounds checking exceeding vector size


My question is different because I am not looking for a range-3v solution. Also, I was specifically asking how to fix the issue with the 2nd for a loop. I accepted the answer below my question already. For I didn't need a second for loop, They showed me how to use a single index by anding it with 1 for odd iterations. This solved my problem!


I am writing a function that will take a vector assuming it is of even length of elements; In my function, I'm creating two temp vectors from the original vector where their elements are {0,2,4,6,...} and {1,3,5,7,...} respectively. Then I am adding the corresponding indexed elements and storing the results into my results vector.

Here is my function:

void sumElementPairsFromVector(const std::vector<int>& values, std::vector<int>& result)
{
    using It = std::vector<int>::const_iterator;
    std::vector<int> temp1, temp2;

    // First lets divide the original vector into two temp vectors
    for (It it1 = values.cbegin(); it1 != values.cend(); it1 += 2)
        temp1.push_back(*it1);

    for (It it2 = values.cbegin() + 1; it2 != values.cend() ; it2 += 2)
        temp2.push_back(*it2);

    // Add each corresponding vector and store that into our results.
    for (std::size_t i = 0; i < values.size() / 2; i++)
        result[i] = temp1[i] + temp2[i];
}

Here is how I'm using it:

int main() 
{         
    std::vector<int> values{ 1,2,3,4,5,6 };
    for (auto i : values)
        std::cout << i << " ";
    std::cout << '\n';

    std::vector<int> results;

    sumElementPairsFromVector(values, results);
    for (auto i : results)
        std::cout << i << " ";
    std::cout << '\n';

    return 0;
}

The expected output should be:

1 2 3 4 5 6
3 7 11

The debug assertion is failing on this line of code from the function:

for (It it2 = values.cbegin() + 1; it2 != values.cend(); it2 += 2 )

I know what is causing the error; on the last iteration after it increments by 2 and goes to check if it2 != values.cend() it is going past the end of the vector. How do I fix this?


Solution

  • I know what is causing the error; on the last iteration after it increments by 2 and goes to check if it2 != values.cend() it is going past the end of the vector. How do I fix this?

    You do not need two different loops for iterate through vector values.

    std::vector<int> temp1, temp2;
    temp1.reserve(values.size() / 2); // reserve the memory
    temp2.reserve(values.size() / 2);
    
    for (std::size_t index = 0; index < values.size(); ++index)
    {
        if (index & 1) temp2.emplace_back(values[index]); // odd index
        else temp1.emplace_back(values[index]);           // even index
    }
    

    Secondly, results did not allocate any memory at the time

    result[i] = temp1[i] + temp2[i];
    

    hence out of bound undefined behavior. You should

    for (std::size_t i = 0; i < std::min(temp1.size(), temp2.size()); i++)
        result.emplace_back(temp1[i] + temp2[i]);
    

    On the other hand, if the goal is to have a resulting vector from the sum of the consecutive pair of elements, the temp1 and temp2 are redundant. The result can be filled simply:

    void sumElementPairsFromVector(const std::vector<int>& values, std::vector<int>& result)
    {
        result.reserve(values.size() / 2);
    
        for (std::size_t index = 0; index < values.size() - 1; index += 2)
            result.emplace_back(values[index] + values[index+1]);
    }