Vector subscript out of range c как исправить

Vector subscript out of range C++ Решение и ответ на вопрос 1214818

Антон219

0 / 0 / 0

Регистрация: 09.06.2013

Сообщений: 72

1

23.06.2014, 05:43. Показов 19463. Ответов 15

Метки нет (Все метки)


Привет, друзья, у меня следующая проблема:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
if (!MeteorVec.empty())
            {
                for (int i = 0; i < MeteorVec.size(); i++)
                {
                    MeteorVec[i]->Moove();
                    if (RectCrossesRect (bullet->borderRect, MeteorVec[i]->borderRect))
                    {
                        MeteorVec[i]->GetsDestroyed(hwnd);
                        bullet->Dissapears();
                        Meteors* p = MeteorVec[i];
                        MeteorVec[i] = MeteorVec.back();
                        MeteorVec.pop_back();
                        delete p;
                    }
                    if (RectCrossesRect (ship->borderRect, MeteorVec[i]->borderRect) && ship->exists)
                    {
                        ship->GetsDestroyed();
                        SetTimer(hwnd, 5, 1000, NULL);
                        Meteors* p = MeteorVec[i];
                        MeteorVec[i] = MeteorVec.back();
                        MeteorVec.pop_back();
                        delete p;
                    }           
                    if (MeteorVec[i]->position.x < 30)
                    {
                        Meteors* p = MeteorVec[i];
                        MeteorVec[i] = MeteorVec.back();
                        MeteorVec.pop_back();
                        delete p;
                    }
                }
            }

все выполняется внутри таймера, MeteorVec — это вектор. Так вот, иногда вылезает ошибка: «vector subscript out of range», может я просто по глупости не вижу очевидного, но никак не могу вкурить, в какой момент он может вылезти за пределы? И как исправить?

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

23.06.2014, 06:19

2

Предположим, что в одном из первых if() происходит удаление последнего элемента вектора (MeteorVec.pop_back()), вектор пуст, но в следующем if() будет обращение по индексу к пустому вектору (например, if (MeteorVec[i]->position.x < 30)), что и вызовет ошибку. После каждого удаления нужно проверять вектор на пустоту, и выполнять нужные действия, в зависимости от результата проверки.



2



Ilot

Эксперт по математике/физикеЭксперт С++

2001 / 1332 / 379

Регистрация: 16.05.2013

Сообщений: 3,450

Записей в блоге: 6

23.06.2014, 09:18

3

Цитата
Сообщение от alsav22
Посмотреть сообщение

Предположим, что в одном из первых if() происходит удаление последнего элемента вектора (MeteorVec.pop_back()), вектор пуст, но в следующем if() будет обращение по индексу к пустому вектору (например, if (MeteorVec[i]->position.x < 30)), что и вызовет ошибку.

Не думаю:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>
struct sd {
  int a;
  sd(int A): a(A)
  {}
};
int main() {
  std::vector<sd> coll;
  //coll.reserve(2);
  coll.push_back(11);
  coll.pop_back();
  coll.pop_back();
  coll.pop_back();
  coll.pop_back();
  std::cout << coll[59].a << std::endl;
 
  return 0;
}

Компилится без проблем и кидает искючение только если векторе не выделена память для элементов. Так что кто кидает исключение вопрос открытый.
Антон219, посмотрите в своей реализации кто может кидать такое исключение.



1



Croessmah

Don’t worry, be happy

17781 / 10545 / 2036

Регистрация: 27.09.2012

Сообщений: 26,517

Записей в блоге: 1

23.06.2014, 11:08

4

Цитата
Сообщение от Ilot
Посмотреть сообщение

Не думаю:

Читаем тут http://www.cplusplus.com/refer… /pop_back/

If the container is not empty, the function never throws exceptions (no-throw guarantee).
Otherwise, it causes undefined behavior.

Так же, если контейнер окажется пустым, то

C++
1
MeteorVec[i] = MeteorVec.back();

будет тоже не здорово себя вести



1



Ilot

Эксперт по математике/физикеЭксперт С++

2001 / 1332 / 379

Регистрация: 16.05.2013

Сообщений: 3,450

Записей в блоге: 6

23.06.2014, 11:35

5

Croessmah, так я же и говорю, что пусть смотрит в своей реализации. Так как в GCC эти методы объявлены так:

C++
1
2
3
4
5
6
7
8
9
10
11
      void
      pop_back() _GLIBCXX_NOEXCEPT
      {
    ...
      }
      reference
      back() _GLIBCXX_NOEXCEPT
      { return *(end() - 1); }
      const_reference
      back() const _GLIBCXX_NOEXCEPT
      { return *(end() - 1); }

Что как бы намекает, что исключение кидать они не могут.



1



alsav22

5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

23.06.2014, 18:33

6

Цитата
Сообщение от Ilot
Посмотреть сообщение

Так что кто кидает исключение вопрос открытый.

Вот код и результат работы:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>
using namespace std;
 
int main() 
{
    vector<int> coll;
    coll.push_back(11);
    coll.pop_back();
    int i = 1;
    if (coll[i] == 3)
        cout << coll[i] << endl;
    else 
        cout << "No!" << endl;
 
    system("pause");
    return 0;
}

Миниатюры

Vector subscript out of range
 



1



Антон219

0 / 0 / 0

Регистрация: 09.06.2013

Сообщений: 72

23.06.2014, 21:42

 [ТС]

7

Вроде исправил!)) Как я понимаю, проблема могла быть, если один из блоков if() пытался обращаться к уже несуществующему элементу. Я поставил цикл for() один и тот же перед каждым блоком if():

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
for (int i = 0; i < MeteorVec.size(); i++)
                {
                    MeteorVec[i]->Moove();
                    if (RectCrossesRect (bullet->borderRect, MeteorVec[i]->borderRect))
                    {
                        MeteorVec[i]->GetsDestroyed(hwnd);
                        bullet->Dissapears();
                        if (i < MeteorVec.size())
                        {
                            delete MeteorVec[i];
                            MeteorVec.erase(MeteorVec.begin() + i);
                        }
                    }
                }
                for (int i = 0; i < MeteorVec.size(); i++)
                {
                    if (RectCrossesRect (ship->borderRect, MeteorVec[i]->borderRect) && ship->exists)
                    {
                        ship->GetsDestroyed();
                        SetTimer(hwnd, 5, 1000, NULL);
                        if (i < MeteorVec.size())
                        {
                            delete MeteorVec[i];
                            MeteorVec.erase(MeteorVec.begin() + i);
                        }
                    }   
                }
                for (int i = 0; i < MeteorVec.size(); i++)
                {
                    if (MeteorVec[i]->position.x < 30)
                    {
                        if (i < MeteorVec.size())
                        {
                            delete MeteorVec[i];
                            MeteorVec.erase(MeteorVec.begin() + i);
                        }
                    }
                }

Удаление тоже изменил, но даже с проверкой if (i < MeteorVec.size()) это не помогло. Помогло только добавление for.
Спасибо за помощь!)
И еще ламерский вопрос: Ilot, как мне понять, по моей реализации, что кидает исключение? Что вообще может его кидать?



0



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

23.06.2014, 21:57

8

Цитата
Сообщение от Антон219
Посмотреть сообщение

как мне понять, по моей реализации, что кидает исключение? Что вообще может его кидать?

Берёте отладчик и смотрите, в каком месте кода возникает исключение.



2



What a waste!

1607 / 1299 / 180

Регистрация: 21.04.2012

Сообщений: 2,727

23.06.2014, 23:05

9

Цитата
Сообщение от alsav22
Посмотреть сообщение

как мне понять, по моей реализации, что кидает исключение? Что вообще может его кидать?

Вообще есть стандарт языка, там всё поведение специфицировано, в кишки своей реализации лезть не обязательно. Справку можно посмотреть например здесь или тут.



1



Эксперт по математике/физикеЭксперт С++

2001 / 1332 / 379

Регистрация: 16.05.2013

Сообщений: 3,450

Записей в блоге: 6

24.06.2014, 08:15

10

alsav22, как видно у вас кидает исключение отладчик, т.е. среда. Как я и говорил. Вы не пробывали запустить релиз сборку?



1



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

24.06.2014, 08:23

11

Цитата
Сообщение от Ilot
Посмотреть сообщение

как видно у вас кидает исключение отладчик, т.е. среда. Как я и говорил.

Отладчику можно? Не обращать внимания? Или о чём речть?



1



Эксперт по математике/физикеЭксперт С++

2001 / 1332 / 379

Регистрация: 16.05.2013

Сообщений: 3,450

Записей в блоге: 6

24.06.2014, 08:28

12

Цитата
Сообщение от alsav22
Посмотреть сообщение

Или о чём речть?

Цитата
Сообщение от Ilot
Посмотреть сообщение

Антон219, посмотрите в своей реализации кто может кидать такое исключение.

Я уже писал о том, что подобное поведение не является стандартом, а определяется реализацией и ваш пример вместе с моим собственно и подтвердил эти слова.



1



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

24.06.2014, 08:34

13

Понятно.



1



1 / 1 / 0

Регистрация: 02.08.2022

Сообщений: 6

05.08.2022, 14:27

14

#include <iostream>
#include <vector>
using namespace std;

int main() {
int n, c = 0;
cin >> n;
vector <int> a;

//ввод
cin >> a[0];
for (int i = 1; i < n; i++) {

if (a[i] > a[i-1]){ c++; }
cin >> a[i];
}

cout << c;

return 0;
}



0



3986 / 3255 / 910

Регистрация: 25.03.2012

Сообщений: 12,104

Записей в блоге: 1

05.08.2022, 15:34

15

Ilya_2009, и чё? Ну говнокод, ну бывает. Зачем он в теме про Vector subscript out of range? Тем более в такой старой теме.



0



SmallEvil

05.08.2022, 16:03


    Vector subscript out of range

Не по теме:

Kuzia domovenok, наверное отрабатывает гроши что заплатили ранее.
Потому как сейчас нет смысла троллить на забытом задворке старого сарая.. Но оно все равно продолжает.
Се ля ви.



0



  • Remove From My Forums
  • Question

  • Hi,

    It’s a problem in problem. I have a C++ project that stucks during runtime (either in debug mode or not), issuing the following error window:

    Microsoft Visual C++ Debug Library

    Debug Assertion Failed!

    Program: …

    File: c:program filesmicrosoft visual studio 8vcincludevector

    Line: 756

    Expression: vector subscript out of range

    For information on how your program can cause an assertion

    Failure, see the Visual C++ documentation on asserts.

    I tried to monitor the fail point but realized that it’s not a fixed one. I’ve read in this forum about the ‘Call stack’ option (Debug + Windows + Call stack) but when I let the program run (F5), the Call stack is cleared.

    Thanks in advance for any help,

    Udi

    Forum: Which function was called before an exception is thrown?

    Yes, call stack.  Debug + Windows + Call stack

Answers

  • Well it’s clear that the subscript is out of range at more than one spot (since you’re saying its «random» where it happens). Your options are to 1. verify the application using asserts or just a watchful eye, 2. use the debugger and see where it crashes, and consider the subscript usage around that point.

  • The reserve-function makes sure that the amount of memory is available, but it doesn’t actually change the «in-use» size of the container. The resize function, on the other han, will allocate and initialize the indicated number of elements. In other words, with resize they will be ready for use, with reserve they won’t.

    You can read more about the STL containers on MSDN, or in any good C++ book. You should consider getting Effective STL by Scott Meyers. That’s a good one.

  • Forum
  • Beginners
  • Vector Subscript Out of Range

Vector Subscript Out of Range

Hi everyone, I have been stuck with this problem for the past two hours. The program asks the user for the names and values of their cars, stores them in tokens, and then puts the tokens into a vector. Then it prints out what the user entered. This program compiles and works up until the last part, at line 36. I don’t know if anything is wrong with the for loop. Everything prints out fine, but I get a «Debug Assertation Failed!» error at line 1234. Expression: vector subscript out of range. Is there something I’m missing here? I don’t know what’s wrong. Thanks for your help and time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// ConsoleApplication2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Token 
{
public:
	string kind;
	double value;
};



int main()
{
	Token get_token();
	vector<Token> cars;
	while (true) 
	{
		string choice;
		cout << "Would you like to add a vehicle?n";
		cin >> choice;
		if (choice == "yes" || choice == "Yes" || choice == "YES")
		{
			Token car = get_token();
			cars.push_back(car);
		}
		else if (choice == "no" || choice == "No" || choice == "NO")
			break;
	}
	for (int i = 0; i <= cars.size(); ++i)
	{
		cout << "Car " << i + 1 << " is a " << cars[i].kind << " and is worth $" << cars[i].value << ".n";
	}
	system("pause");
    return 0;
}

Token get_token()
{
	Token tok;
	string kind;
	double value;
	cout << "Enter what type of vehicle you have.n";
	cin >> kind;
	cout << "Enter what it's worth.n";
	cin >> value;
	tok.kind = kind;
	tok.value = value;
	return tok;
}

Last edited on

Figured it out literally 10 minutes later. The for loop should be

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

instead of what it is now. This is because cars.size() is not an int, instead it is size_t, which equals some usual «unsigned» type.

Last edited on

The problem had nothing to do with the type. The problem was that valid indices in a vector fall into the range 0 to vectorSize — 1. By changing i <= cars.size() to i < cars.size() you stop yourself from trying to use cars.size() as an index (which is beyond the valid range of indices).

@booradley60

Wow, I tried that earlier, and it didn’t work, but now it suddenly does. Thanks, I was going crazy

Topic archived. No new replies allowed.

Понравилась статья? Поделить с друзьями:
  • Vec3 pool size error nullpointerexception null
  • Vdw0401m ошибка е2
  • Vdo ошибка 007
  • Vdi broker initialization failed как исправить
  • Vdh002 macbook ошибка