C ++ доступ к вектору - PullRequest
       7

C ++ доступ к вектору

2 голосов
/ 22 ноября 2010

У меня есть std::vector, который содержит мой собственный класс, и я должен получить доступ к его функциям и пустотам.

class A
{
private: 
     int var;
     vector<string> vec;

public:
     void setVar(int i) { var = i; }
     void setVec(vector<string> a) { vec = a; }
};

У меня также есть функции возврата, но я не удосужился их напечатать. И я включил все необходимые файлы.

int main()
{
    vector<A> vec;
    for (int i = 0; i < 10; i++)
    {
        A tmp;
        tmp.setVar(i);
        vec.push_back(tmp);
    }

    for (int i = 0; i < 10; i++)
    {
        vector<string> tmp;
        tmp.push_back("1");
        tmp.push_back("2");
        tmp.push_back("3");
        vec.at(i).setVec(tmp);  //Works sometimes or causes error std::out_of_range
        vec[i].setVec(tmp);     //Crashes the whole programm
    }
}

Так как мне установить эти переменные, так как vector инициализирован?

Я использую g ++, и это не настоящий код, потому что мой настоящий код грязный.

Error for vec.at(i).setVec(tmp);
Error is:  terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check

Ответы [ 4 ]

2 голосов
/ 22 ноября 2010

Код, который вы разместили, по-прежнему не будет компилироваться (не объявлено tmp в первом цикле), поэтому позвольте мне в общих чертах объяснить, что происходит.

Вы упомянули два вида ошибок:

vec.at(i).setVec(tmp);  //Works sometimes or causes error std::out_of_range

Функция at пытается быть безопасной - она ​​сначала проверяет длину вектора, затем возвращает элемент данного индекса или выдает std::out_of_range, если вектор не содержит элемент такогоindex.

Второй случай:

vec[i].setVec(tmp);     //Crashes the whole programm

Оператор [] ведет себя так же, как функция at() для векторов, но это не "безопасно", так как оно не делает никаких границ.проверка.Следовательно, если вы пытаетесь получить доступ к 4-му элементу 3-элементного элемента, вы просто получаете доступ к некоторому случайному месту в вашей памяти (это может быть другая, не связанная переменная, например, может быть что-то еще).Если вам повезет, ваша программа потерпит крах после этого.Если вам не повезло, у вас будут проблемы с повреждением памяти и очень странные ошибки, которые трудно найти.

Решение вашей проблемы:

a) Заменитьvec[i] с vec.at(i) - работайте так же (ну, чуть-чуть медленнее, но вы этого не почувствуете), и вы в безопасности.

b) Тогда: посмотритево всех местах, где вы на самом деле выполняете поиск векторов, и в каждом месте останавливаетесь на секунду и думаете: «Насколько велик этот вектор в данный момент? Я уверен, что элемент этого индекса существует?».

Скорее всего, вы быстро найдете свою ошибку.

2 голосов
/ 22 ноября 2010

Какой компилятор вы используете? Я на самом деле очень удивлен, что std::vector<std::string> tmp("1","2","3"); даже компилируется!

Если честно, я понятия не имею, как он называется, но держу пари, что он не делает то, что вы ожидаете, что я считаю:

std::vector<std::string> tmp;
tmp.push_back("1");
tmp.push_back("2");
tmp.push_back("3");

Для справки: boost.assign и C ++ 0x предоставляют тип инициализации контейнера, который вы пытались достичь.

1 голос
/ 22 ноября 2010

Я попробовал ваш код в VS2010 и не смог воспроизвести проблему, которую вы описали.Конечно, передача вектора по значению не очень хорошая идея, это должна быть ссылка на константу, но она не может вызвать такую ​​ошибку.Принимая во внимание тот факт, что 'std :: out_of_range' вызвано, наиболее вероятная причина в том, что в вашем векторе нет элемента с таким индексом.Для тестирования вы можете проверить, если i < vec.size(), прежде чем получить доступ к vec[i] (или vec.at(i))

0 голосов
/ 22 ноября 2010

Я нашел проблему.Это было в функции, которая обрабатывает размер вектора.Видимо вектор был пустым.Тупая ошибка.Спасибо всем за ответы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...