С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Red Planet
49 / 10 / 2
Регистрация: 20.09.2009
Сообщений: 263
#1

На что ссылается итератор после remove(*it) - C++

29.03.2012, 21:11. Просмотров 912. Ответов 16
Метки нет (Все метки)

Здравствуйте! Не понимаю, почему итератор ссылается на удаленный из списка элемент?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <vcl>
#include <iostream>
#include <fstream>
#include <list>
#include <vector>
#include <string>
 
using namespace std;
 
 
 
// -----------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[]) {
    list<int> mylist;
    list<int>::iterator it1;
 
    for (int i = 1; i < 10; i++)
        mylist.push_back(i * 10);
 
    it1 = mylist.begin();
    it1++;
 
    while (*it1 < 70) {
        int it1_value = *it1;
        cout << "Before: " << it1_value << endl;
 
        mylist.remove(*it1);
 
        it1_value = *it1;
        cout << "After: " << it1_value << endl;
        it1++;
    }
 
    it1 = mylist.begin();
    cout << endl;
    for (;  it1 != mylist.end(); it1++)
        cout << *it1 << " " ;
    cout << endl;
    system("pause");
    return 0;
}
Вывод показывает, что после удаления элемента из списка и применения

C++
1
it1_value = *it1;
it1_value станет равным значению удаленного элемента. Его же (элемента) не существует. Нелогично.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.03.2012, 21:11
Здравствуйте! Я подобрал для вас темы с ответами на вопрос На что ссылается итератор после remove(*it) (C++):

как создать копию объекта, на который ссылается итератор? - C++
Есть шаблонная фукнция, в которую передается итератор с произвольным доступом (IT). Необходимо внутри функци создать копию элемента...

Функция remove() удаляет только заранее запланированые файлы, выдавая ошибку на remove (STRING) - C++
Салем, начал изучать файловую работу в С++, и столкнулся с такой проблемой, что функция remove() соглашается удалять только заранее...

Откуда берется значение указателя после удаления памяти на которую он ссылается? - C++
Всем привет. Почему при удалении памяти указатель еще работает? Пример программы: #include &lt;iostream&gt; #include &lt;stdio.h&gt; ...

Реализовать двусвязный список (list), итератор (iterator) и константный итератор (сonst_iterator) для списка - C++
не могу понять что должно быть результатом. может подскажете примеры? пожалуйста. Задание: Реализовать двусвязный список (list),...

Реализовать аппликативный оператор MY-REMOVE-IF с интерфейсом и семантикой, аналогично стандартному REMOVE-IF - Lisp
Реализовать аппликативный оператор MY-REMOVE-IF с интерфейсом и семантикой, аналогично стандартному REMOVE-IF.

Пропал Диск Д после удаления HP Remove Recovery - Windows
Добрый день, подскажите пожалуйста, можно ли как-то востановить диск Д (на нем была установлена виртуальная машина и выполнялось hp...

16
antoha398
155 / 155 / 3
Регистрация: 29.03.2012
Сообщений: 418
29.03.2012, 21:21 #2
Получается, что элемент удален только из списка, а в памяти он остался и итератор по прежнему содержит адрес памяти.
1
villu
203 / 204 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
29.03.2012, 21:59 #3
после удаления из листа его итератор вообще становится невалидным.
так что код
C++
1
2
it1_value = *it1;
cout << "After: " << it1_value << endl;
невалидный и опасный.
1
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
29.03.2012, 23:43 #4
villu, А это откуда взято интересно? Все несколько проще подозреваю.
Removes from the list all the elements with a specific value. This calls the destructor of these objects and reduces the list size by the amount of elements removed.
Notice that a global algorithm function, remove, exists with a similar behavior but operating between two iterators.
А std::remove не делает ничего иного, кроме как перемещает элемент в конец и возвращает итератор на начало удаленных элементов.
1
villu
203 / 204 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
30.03.2012, 00:02 #5
list::remove это не std::remove и делает не тоже самое.
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
30.03.2012, 00:09 #6
villu,
Notice that a global algorithm function, remove, exists with a similar behavior but operating between two iterators.
Я как бэ цитату для кого привел?
0
villu
203 / 204 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
30.03.2012, 00:11 #7
да, не там прочитал.
Но итератор после удаления все равно становится невалидным.
1
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
30.03.2012, 00:21 #8
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    void remove(const _Ty& _Val_arg)
        {   // erase each element matching _Val
        const _Ty _Val = _Val_arg;  // in case it's removed along the way
        const _Nodeptr _Phead = this->_Myhead;
        _Nodeptr _Pnode = this->_Nextnode(_Phead);
 
        while (_Pnode != _Phead)
            if (_Pnode->_Myval == _Val)
                {   // match, remove it
                const _Nodeptr _Pprev = this->_Prevnode(_Pnode);
                const _Nodeptr _Perase = _Pnode;
                _Pnode = this->_Nextnode(_Pnode);
 
                this->_Nextnode(_Pprev) = _Pnode;
                this->_Prevnode(_Pnode) = _Pprev;
                this->_Freenode(_Perase);
 
                --this->_Mysize;
                }
            else
                _Pnode = this->_Nextnode(_Pnode);
        }
Реализация из студии.
Но то, что использоваться это не стоит и что при первом же изменении итератор станет недействительным согласен.

Добавлено через 4 минуты
Признаю свою неправоту.
15 Effects: Erases all the elements in the list referred by a list iterator i for which the following conditions
hold: *i == value, pred(*i) != false. Invalidates only the iterators and references to the erased
elements.
16 Throws: Nothing unless an exception is thrown by *i == value or pred(*i) != false.
17 Remarks: Stable.
18 Complexity: Exactly size() applications of the corresponding predicate.
0
villu
203 / 204 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
30.03.2012, 00:28 #9
ну так об этом и была речь. Никуда он (list::remove) ничего не двигает, просто удаляет и меняет указатели.
это к
А std::remove не делает ничего иного, кроме как перемещает элемент в конец и возвращает итератор на начало удаленных элементов.
а вот он (std::remove) как раз делает очень по тупому и неэффективно, сдвигая элементы на место удаленных.
0
silent_1991
Эксперт С++
4989 / 3046 / 149
Регистрация: 11.11.2009
Сообщений: 7,028
Завершенные тесты: 1
30.03.2012, 19:07 #10
Цитата Сообщение от villu Посмотреть сообщение
а вот он (std::remove) как раз делает очень по тупому и неэффективно, сдвигая элементы на место удаленных.
Т.е. было бы эффективнее перевыделить память и скопировать в неё все нужные элементы? (применительно к вектору, например). Или речь велась исключительно о списках?
0
villu
203 / 204 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
30.03.2012, 21:16 #11
ну про список же говорили. для списка std::remove не эффективен. и не только для списка
Т.е. было бы эффективнее перевыделить память и скопировать в неё все нужные элементы?
а вот именно так и делает другой алгоритм (копирует только нужное в смысле).
1
Red Planet
49 / 10 / 2
Регистрация: 20.09.2009
Сообщений: 263
31.03.2012, 20:59  [ТС] #12
Цитата Сообщение от villu Посмотреть сообщение
std::remove не эффективен
Кстати, есть небольшая статья по нему. Сам был удивлен, когда прочитал, что алгоритм remove не совсем удаляет элементы.
0
silent_1991
Эксперт С++
4989 / 3046 / 149
Регистрация: 11.11.2009
Сообщений: 7,028
Завершенные тесты: 1
31.03.2012, 21:03 #13
Red Planet, чтобы "совсем удалял", нужно использовать erase-remove idiom.
1
alex_x_x
бжни
2450 / 1655 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
31.03.2012, 21:06 #14
Цитата Сообщение от Red Planet Посмотреть сообщение
Кстати, есть небольшая статья по нему. Сам был удивлен, когда прочитал, что алгоритм remove не совсем удаляет элементы.
алгоритм не может удалять элементы контейнера, так как удаление не очень общая операция
так что на самом деле это логичное решение
1
Red Planet
49 / 10 / 2
Регистрация: 20.09.2009
Сообщений: 263
31.03.2012, 21:16  [ТС] #15
silent_1991, насчет erase-remove idiom. Использование этого необходимо если мы имеем дело с вектором и используем алгоритм STL. В моей задаче нужно удалить из списка, то есть достаточно будет воспользоваться

C++
1
mylist.erase(it_from_incl, it_to_not_incl);
Добавлено через 56 секунд
Цитата Сообщение от alex_x_x Посмотреть сообщение
алгоритм не может удалять элементы контейнера, так как удаление не очень общая операция
так что на самом деле это логичное решение
Согласен.
0
31.03.2012, 21:16
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.03.2012, 21:16
Привет! Вот еще темы с ответами:

Что за технология, когда ссылается только на каталог? - C# ASP.NET
Я тут хожу по сайтам и как говориться, все чаще замечаю, что они используют такую вещь, что при переходе по ссылке - ссылка ссылается на...

Особый итератор словаря. Итератор возвращающий нужные комбинации - Алгоритмы
Немогу разобраться, как написать итератор. У меня есть словарь, ключи это координаты, а значения это либо ноль, либо единичка (True и...

Novicorp Remove Windows 10 Spying,кто что слышал об этой программе ? - Windows 10
Novicorp Remove Windows 10 Spying,кто что слышал об этой программе или пользовался ей.

Особый итератор словаря. Медленный итератор - Python
Не могу разобраться, как написать итератор. У меня есть словарь, ключи это координаты, а значения это либо ноль, либо единичка (True и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.