Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
 Аватар для Red Planet
49 / 10 / 3
Регистрация: 20.09.2009
Сообщений: 263

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

29.03.2012, 21:11. Показов 1626. Ответов 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.03.2012, 21:11
Ответы с готовыми решениями:

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

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

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

16
157 / 157 / 27
Регистрация: 29.03.2012
Сообщений: 418
29.03.2012, 21:21
Получается, что элемент удален только из списка, а в памяти он остался и итератор по прежнему содержит адрес памяти.
1
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
29.03.2012, 21:59
после удаления из листа его итератор вообще становится невалидным.
так что код
C++
1
2
it1_value = *it1;
cout << "After: " << it1_value << endl;
невалидный и опасный.
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.03.2012, 23:43
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
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
30.03.2012, 00:02
list::remove это не std::remove и делает не тоже самое.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
30.03.2012, 00:09
villu,
Notice that a global algorithm function, remove, exists with a similar behavior but operating between two iterators.
Я как бэ цитату для кого привел?
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
30.03.2012, 00:11
да, не там прочитал.
Но итератор после удаления все равно становится невалидным.
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
30.03.2012, 00:21
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
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
30.03.2012, 00:28
ну так об этом и была речь. Никуда он (list::remove) ничего не двигает, просто удаляет и меняет указатели.
это к
А std::remove не делает ничего иного, кроме как перемещает элемент в конец и возвращает итератор на начало удаленных элементов.
а вот он (std::remove) как раз делает очень по тупому и неэффективно, сдвигая элементы на место удаленных.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
30.03.2012, 19:07
Цитата Сообщение от villu Посмотреть сообщение
а вот он (std::remove) как раз делает очень по тупому и неэффективно, сдвигая элементы на место удаленных.
Т.е. было бы эффективнее перевыделить память и скопировать в неё все нужные элементы? (применительно к вектору, например). Или речь велась исключительно о списках?
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
30.03.2012, 21:16
ну про список же говорили. для списка std::remove не эффективен. и не только для списка
Т.е. было бы эффективнее перевыделить память и скопировать в неё все нужные элементы?
а вот именно так и делает другой алгоритм (копирует только нужное в смысле).
1
 Аватар для Red Planet
49 / 10 / 3
Регистрация: 20.09.2009
Сообщений: 263
31.03.2012, 20:59  [ТС]
Цитата Сообщение от villu Посмотреть сообщение
std::remove не эффективен
Кстати, есть небольшая статья по нему. Сам был удивлен, когда прочитал, что алгоритм remove не совсем удаляет элементы.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
31.03.2012, 21:03
Red Planet, чтобы "совсем удалял", нужно использовать erase-remove idiom.
1
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
31.03.2012, 21:06
Цитата Сообщение от Red Planet Посмотреть сообщение
Кстати, есть небольшая статья по нему. Сам был удивлен, когда прочитал, что алгоритм remove не совсем удаляет элементы.
алгоритм не может удалять элементы контейнера, так как удаление не очень общая операция
так что на самом деле это логичное решение
1
 Аватар для Red Planet
49 / 10 / 3
Регистрация: 20.09.2009
Сообщений: 263
31.03.2012, 21:16  [ТС]
silent_1991, насчет erase-remove idiom. Использование этого необходимо если мы имеем дело с вектором и используем алгоритм STL. В моей задаче нужно удалить из списка, то есть достаточно будет воспользоваться

C++
1
mylist.erase(it_from_incl, it_to_not_incl);
Добавлено через 56 секунд
Цитата Сообщение от alex_x_x Посмотреть сообщение
алгоритм не может удалять элементы контейнера, так как удаление не очень общая операция
так что на самом деле это логичное решение
Согласен.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
31.03.2012, 21:17
Red Planet, разумеется. разговор ведь шёл об std::remove.
1
 Аватар для Red Planet
49 / 10 / 3
Регистрация: 20.09.2009
Сообщений: 263
31.03.2012, 21:24  [ТС]
Вопрос закрыт. Благодарю всех участвовавших в обсуждении.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
31.03.2012, 21:24
Помогаю со студенческими работами здесь

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

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

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

List.remove() vs asList.remove()
Всем привет. Хотел решить одну задачку тут на форуме, но что-то у меня все из рук валится, и в переносном смысле тоже. Немного...

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


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru