Получать «векторный индекс вне диапазона» только в Visual Studio, если переменные данные содержат целое число больше, чем все элементы вектора? - PullRequest
0 голосов
/ 16 января 2020
  cin >> q;
  while (q--)
  {

    cin >> data;
    //if this value is greater than all the elements of the vector throwing error
    vector<int>::iterator low = lower_bound(v.begin(), v.end(), data); //does the lower bound

    if (v[low - v.begin()] == data)
        cout << "Yes " << (low - v.begin() + 1) << endl;
    else
        cout << "No " << (low - v.begin() + 1) << endl;// while this should be the output
   }

, если вектор v содержит 1 2 3 4 5 6 7 8, и мы вводим данные 9, тогда его ошибка отображается в виде нижнего индекса вектора вне диапазона.

Ответы [ 2 ]

2 голосов
/ 16 января 2020

Согласно документации std::lower_bound() на cppreference.com:

Возвращает итератор, указывающий на первый элемент в диапазоне [first, last), который составляет не менее чем (то есть больше или равно ) value, или last, если такой элемент не найден .

В вашем вызове в lower_bound(v.begin(), v.end(), data), когда v равно {1 2 3 4 5 6 7 8} и data равно 9, в v нет элемента, который равен >= data, поэтому v.end() возвращается в low. Таким образом, low - v.begin() равно v.end() - v.begin(), что создает индекс (8), выходящий за пределы вектора (допустимые индексы 0-7). Какой Visual Studio затем предупреждает вас.

Вам необходимо добавить проверку для условия, когда std::lower_bound() не находит соответствующий элемент:

auto low = lower_bound(v.begin(), v.end(), data);

if (low == v.end()) // <-- ADD THIS!
{
    cout << "Not found" << endl;
}
else
{
    auto index = low - v.begin();

    if (v[index] == data)
        cout << "Yes " << (index + 1) << endl;
    else
        cout << "No " << (index + 1) << endl;
}
2 голосов
/ 16 января 2020

Получение «векторного индекса вне диапазона» только в Visual Studio ...

Visual Studio верен в этом утверждении.

Отладочная версия среды выполнения Visual C ++ проверит индексы std::vector и сообщит о проблемах при наличии доступа за пределами допустимого диапазона.

Другой используемый вами компилятор не сообщает вам об этой ошибке, поскольку в действительности operator [] для std::vector имеет неопределенное поведение при доступе к элементу за пределами допустимого. Таким образом, вы ошибаетесь, когда видите вывод - ваша программа имеет ошибку «один за другим».

Чтобы доказать это, вот ваш код, но он использует at() вместо [ ] для доступа элементы:

#include <vector>
#include <iostream>

int main()
{
    std::vector<int> v = {1,2,3,4,5,6,7,8};
    std::vector<int>::iterator low = lower_bound(v.begin(), v.end(), 9); 
    if (v.at(low - v.begin()) == 9)
        std::cout << "Yes " << (low - v.begin() + 1) << std::endl;
    else
        std::cout << "No " << (low - v.begin() + 1) << std::endl;// while this should be the output
}

Пример в реальном времени

Обратите внимание на исключение std::out_of_range? Теперь вы получите ту же ошибку, независимо от того, какой компилятор вы будете использовать, поскольку vector::at() выполняет проверку границ.


Теперь вот ваш оригинальный код:

Оригинал code

Обратите внимание, что вы получаете выходные данные, но вы «молча» обращаетесь к элементу «за пределами», поэтому поведение программы не определено.

...