Невозможно удалить элемент по индексу из вектора C ++ - PullRequest
0 голосов
/ 11 июня 2018

Я пытаюсь выучить векторы в C ++ , поэтому я пишу очень простой код.По сути, у меня есть вектор, который содержит указатель на структуру человека.Что-то вроде этого:

typedef struct _person
{
    unsigned long id;
    char* name;
    unsigned long age;
}person;

Тогда у меня есть вектор, который определяется следующим образом:

vector<person*> MyPersons;

Затем для тестирования я создал некоторую структуру человека и протолкнул ихк вектору через push_back функцию.Теперь, например, я хочу удалить первого человека, которому 25 лет, из моего вектора.Итак, я делаю поиск в векторе и получаю индекс этого человека, затем стираю этот индекс из вектора.

for(size_t i = 0; i < MyPersons.size(); i++)
{
    pperson = MyPersons.at(i);
    if(pperson->age == 25)
    {
        index = i;
        break;
    }
}

MyPersons.erase(MyPersons.begin() + index )

Теперь нужно удалить этот элемент из списка, верно?Но вместо этого он выдает ошибку:

Ошибка отладки!

Выражение: итератор стирания вектора вне диапазона

Но это невозможно.Я отлаживал свой код в Visual Studio и вижу, что значение индекса допустимо.Размер MyPersons равен 5, а индекс равен 2.

Любая помощь очень ценится.С уважением * * 1023

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

Вам не нужна преамбула typedef struct _person, это C-ism.

struct person
{
    unsigned long id;
    std::string name;
    unsigned long age;
}

Вам также не нужно new объекты, они могут быть значениями

std::vector<person> people;

Чтобы удалить первого человека в возрасте 25 лет:

auto it = std::find_if(people.begin(), people.end(), [](person & p) { return p.age = 25; });
if (it != people.end()) people.erase(it);

Чтобы удалить всех людей в возрасте 25 лет:

auto it = std::remove_if(people.begin(), people.end(), [](person & p) { return p.age = 25; });
people.erase(it, people.end());
0 голосов
/ 11 июня 2018

Возможно, проблема в том, что index инициализируется значением, не входящим в диапазон MyPersons, поэтому, если это значение не найдено, вы получите ошибку.

Вам следует использовать стандартные алгоритмыдля этого типа задачи, чтобы удалить первые person* с возрастом 25, вы можете использовать:

auto itr = std::find_if(MyPersons.cbegin(), MyPersons.cend(),
                       [] (person* pperson) { return pperson->age == 25; });
if (itr != MyPersons.cend()) MyPersons.erase(itr);

Чтобы удалить все person* с возрастом 25, вы можете использовать:

MyPersons.erase(std::remove_if(MyPersons.begin(), MyPersons.end(),
                [] (person* pperson) { return pperson->age == 25; }),
                MyPersons.end());

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

Кроме того, вы, вероятно, поступаете неправильно, сохраняя указатели на ваши данные вstd::vector.

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