stl списки
#include <iostream>
using namespace std;
int main ()
{
list<int*> l;
int *i, *ii, *iii;
i = new int;
ii = new int;
iii = new int;
l.push_back (i);
l.push_back (ii);
l.push_back (iii);
list<int*>::iterator it = l.begin();
while (it != l.end())
{
delete (*it);
l.remove (*it);
++it;
}
return 1;
}
Объясните пожалуйста почему работа приложения завершается аварийно.
[/FONT]
list<int*>::iterator it = l.begin();
while (it != l.end())
{
delete (*it);
l.remove (*it); // невалидный указатель!
++it;
}
[/FONT]
Поменяй местами delete и list::remove, а лучше используй list::erase(it) вместо list::remove при наличии итератора.
Я не понял зачем? Ведь мне необходимо сначала освободить память, выделенную для указателя, а потом удалить элемент списка.
Я правильно понимаю, что list::erase() используется для удаления единичного объекта, в то время как list::remove() удаляет все элементы из списка с тем же значением?
[FONT=Courier New]
Вобщем проблему я решил таким способом:[/FONT]
[FONT=Courier New]
int main ()
{
list<int*> l;
int* i = new int;
(*i) = 1;
int* ii = new int;
(*ii) = 2;
int* iii = new int;
(*iii) = 1;
l.push_back (i);
l.push_back (ii);
l.push_back (iii);
list<int*>::iterator it = l.begin();
while (it != l.end())
{
if ((*(*it)) == 1)
{
delete (*it);
l.erase (it++);
}
else
++it;
}
return 1;
}
В предыдущей реализации после удаления элемента я терял указатель на следующий элемент. При теперешней реализации я перед тем как передать итератор на удаление перехожу на следующий элемент. Постфиксная форма инкремента возвращает указатель на текущий элемент, но при этом итератор переходит на следующий элемент. Немного коряво объяснил, но надеюсь я ничего не напутал.
[/FONT]
if (**it == 1) {
delete *it;
l.erase(it--);
}
}
if (**it == 1) {
delete *it;
l.erase(it--);
}
}
А насколько правомерна операция декремента на итераторе, который в начале списка?
Не опасна ли конструкция
?
Надо будет посмотреть стандарт.