Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

stl списки

14K
22 июля 2007 года
crot
16 / / 25.07.2006
[FONT=Courier New]#include <list>
#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]
1.8K
23 июля 2007 года
_const_
229 / / 26.11.2003
Цитата: crot
[FONT=Courier New]
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 при наличии итератора.

14K
23 июля 2007 года
crot
16 / / 25.07.2006
Цитата:
Поменяй местами 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]

3
23 июля 2007 года
Green
4.8K / / 20.01.2000
Достаточно так:
 
Код:
for ( list<int*>::iterator it = l.begin(); it != l.end(); ++it) {
    if (**it == 1) {
        delete *it;
        l.erase(it--);
    }
}
350
24 июля 2007 года
cheburator
589 / / 01.06.2006
Цитата: Green
Достаточно так:
 
Код:
for ( list<int*>::iterator it = l.begin(); it != l.end(); ++it) {
    if (**it == 1) {
        delete *it;
        l.erase(it--);
    }
}


А насколько правомерна операция декремента на итераторе, который в начале списка?
Не опасна ли конструкция

 
Код:
l.begin()--;

?
3
24 июля 2007 года
Green
4.8K / / 20.01.2000
IMHO вполне правомерна. Во всяком случае, код работает.
Надо будет посмотреть стандарт.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог