0

I am just practicing c++ on leetcode: https://leetcode.com/problems/asteroid-collision/description/

and I have problem with vector overflow.

terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
class Solution {
public:
    vector<int> asteroidCollision(vector<int>& asteroids)
    {
        auto left = 0;
        auto right = asteroids.size() - 1;
        while (left <= right) {

            if (left == right) {
                return asteroids;
            }

            if ((asteroids.at(left) > 0 && asteroids.at(right) < 0) || (asteroids.at(left) < 0 && asteroids.at(right) > 0)) {
                if (abs(asteroids.at(left)) == abs(asteroids.at(right))) {
                    asteroids.erase(asteroids.begin() + right);

                    // until this everything seems fine
                    asteroids.erase(asteroids.begin() + left);

                    left++;
                    right--;
                }
                if (abs(asteroids.at(left)) > abs(asteroids.at(right))) {
                    asteroids.erase(asteroids.begin() + right);
                    right--;
                }
                if (abs(asteroids.at(left)) < abs(asteroids.at(right))) {
                    asteroids.erase(asteroids.begin() + left);
                    left++;
                }
            }
            cout << asteroids.size();
        }
        return asteroids;
    }
};

I know that erase shrinks the size of my vector, but I can't see how the out_of_range occures

EDIT: this is my first version of the code, I know that I can write it more simpler(like less if statements or abs() ect. ), but fisrt I want to know the reason of codes failure.

mch
  • 9,424
  • 2
  • 28
  • 42
  • On which line does the problem occur? Anyway, one of the calls to the `at` method has an out of range index. Shouldn't be too complicated to find out. – Jabberwocky Aug 04 '23 at 10:19
  • 1
    [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – Jesper Juhl Aug 04 '23 at 10:21
  • 2
    Don't, just don't. Do NOT use leetcode to improve your C++ coding, you are more likely to pickup very bad C++ coding habits. For your code, do you know the [erase/remove](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove) idiom? – Pepijn Kramer Aug 04 '23 at 10:52
  • 3
    Leetcode is NOT a good way to learn C++. Good sources to learn cpp from are : A [recent C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) or have a go at https://www.learncpp.com/ (that's pretty decent, and pretty up-to-date). For C++ reference material use : [cppreference](https://en.cppreference.com/w/). And after you learned the C++ basics from those sources, look at the [C++ coreguidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines) regularely to keep up-to-date with the latest guidelines. – Pepijn Kramer Aug 04 '23 at 10:54
  • In the first if-case you erase two members, which reduces size by two. Shouldn't that also reduce `right` by two? And I think `left` should perhaps stay at 0 after erasing the leftmost element? – BoP Aug 04 '23 at 11:00
  • 4
    If your vector is empty, you enter the `while` loop and pretty much immediately access and invalid index. – Mike Vine Aug 04 '23 at 11:18

1 Answers1

2

You loop for the original size of the vector, but inside the loop you reduce the size of the vector, so you end up accessing out of bounds when accessing beyond the new reduced size.

If the vector initially holds 10 elements you'll loop 10 times and access elements 0-9. And if you erase 1 element, then the only valid indices will be 0-8, so once you hit index 9 you are out-of-bounds.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70