Векторные итераторы несовместимы: ошибка времени выполнения - PullRequest
1 голос
/ 02 апреля 2012

У меня сейчас проблемы с деструктором класса, который содержит вектор объектов.Приложение работает нормально, однако после освобождения кучи оно выдает ошибку.

Вот код моего деструктора:

    ~StaticNetwork(void) { // clear memory
    for(vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); )
        nodes.erase(iter++);
}

И узлы добавляются в сеть следующим образом:

    if((temp = is_already_added(regex_d[1])) >= 0) // check if the src node has already been added
            {
                if((temp1 = is_already_added(regex_d[2])) >= 0) // check if the next_hop has already been added
                {
                    nodes[temp]->add_n_vchannels(regex_d[5]);
                    nodes[temp]->add_next_hop(nodes[temp1]);
                }
                else // the next_hop has not been added 
                {
                    Node *anext_hop = new Node(regex_d[2]);

                    nodes[temp]->add_next_hop(anext_hop);
                    nodes[temp]->add_n_vchannels(regex_d[5]);

                    nodes.push_back(anext_hop); //  add next hop        
                    param.n_of_nodes++;
                }       
            }

Сеть состоит из указателей на фактические узлы.

Любая помощь / предложение / ссылка / (конструктивная) критика будет принята с благодарностью.

Ответы [ 3 ]

2 голосов
/ 02 апреля 2012

Ваша итерация над контейнером неверна.Если node является членом класса, игнорируйте его, поскольку деструктор вектора позаботится об этом.Если он не является членом, и вы действительно хотите удалить все элементы, самое простое - вызвать node.clear() (обратите внимание, что оба кода эквивалентны вашему коду, но они утечут указанную память, если им будет управлять ваш класс)

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

for ( std::vector<Node*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
   delete *it;

Обратите внимание, что я не изменял сам контейнер, только содержащиеся в нем элементы.

1 голос
/ 02 апреля 2012

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

0 голосов
/ 02 апреля 2012

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

Более того, стирание делает недействительными итераторы, следующие за стертыми элементами, поэтому проверка iter != nodes.end(); вызывает ошибку, когда вы увеличиваете указатель за ним.

В любом случае, вы можете написать код, показанный Дэвидом Родригесом - dribeas.

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