Форум программистов, компьютерный форум CyberForum.ru

Почему нет ошибок? - C++

Восстановить пароль Регистрация
 
IVSasha
6 / 6 / 2
Регистрация: 29.07.2015
Сообщений: 61
19.09.2015, 15:01     Почему нет ошибок? #1
Программа ведь не должна работать

После вызова erase() для элемента, на который ссылается итератор it,
итератор становится недействительным. Любые попытки использования it
после удаления элемента без повторной инициализации - даже команда ++it
- приводят к непредсказуемым последствиям.
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
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include <iterator>
 
int main() {
    typedef std::multimap<std::string, float> StringFloatMMap;
 
    StringFloatMMap c;
 
    c.insert(std::make_pair("String1", 1));
    c.insert(std::make_pair("String2", 2));
    c.insert(std::make_pair("String3", 3));
    c.insert(std::make_pair("String4", 4));
    c.insert(std::make_pair("String5", 5));
    c.insert(std::make_pair("String6", 6));
 
    for (StringFloatMMap::iterator it = c.begin(); it != c.end(); ++it)
        if (it->second == 5)
            c.erase(it);
            
    
    return 0;
}
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.09.2015, 15:01     Почему нет ошибок?
Посмотрите здесь:

Не работает программа, ошибок компиляции нет. C++
C++ Синтаксических и арифметических ошибок в цикле вроде как нет, но он не работает
ошибок в компиляции нет, а при работе выходит ошибка, почему? C++
При компилировании компилятор вылетает,нет ли ошибок, или почему он так? C++
Компилируется без ошибок, но командная строка, почему то, сразу же закрывается C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Enno
265 / 168 / 38
Регистрация: 25.08.2014
Сообщений: 1,088
Записей в блоге: 1
19.09.2015, 15:06     Почему нет ошибок? #2
Не работать тоже не должна.
Ты просто вызываешь оператор префиксного инкремента для недействительного итератора. Попробуй "разыменовать" этот итератор, обращаясь к какому-нибудь члену, тогда и полетит.
IVSasha
6 / 6 / 2
Регистрация: 29.07.2015
Сообщений: 61
19.09.2015, 16:25  [ТС]     Почему нет ошибок? #3
Цитата Сообщение от Enno Посмотреть сообщение
Попробуй "разыменовать" этот итератор, обращаясь к какому-нибудь члену, тогда и полетит.
После c.erase(it) обращаюсь к удаленному элементу
C++
1
std::cout << "[" << it->first << "; " << it->second << "] deleted." << std::endl;
Вот это выводит в консоль
[; 5] deleted.
Т.е. ошибок нет даже при разыменовании удаленного элемента

Добавлено через 1 час 10 минут
up...
Kerry_Jr
Модератор
 Аватар для Kerry_Jr
1868 / 1664 / 580
Регистрация: 14.05.2014
Сообщений: 4,779
Записей в блоге: 1
Завершенные тесты: 5
19.09.2015, 16:30     Почему нет ошибок? #4
IVSasha, разыменование невалидного итератора есть UB
IVSasha
6 / 6 / 2
Регистрация: 29.07.2015
Сообщений: 61
19.09.2015, 16:33  [ТС]     Почему нет ошибок? #5
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
разыменование невалидного итератора есть UB
теперь все ясно. спасибо
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
19.09.2015, 16:43     Почему нет ошибок? #6
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от IVSasha Посмотреть сообщение
Любые попытки использования it
после удаления элемента без повторной инициализации - даже команда ++it
- приводят к непредсказуемым последствиям.
под "непредсказумемыми" следует понимать UB (неопределенное поведение).
то есть может быть все, что угодно:

1.
программа может каким то чудом работать.

2.
а потом падать в зависимости от фазы луны.

3.
сразу же протянуть лапки к верху

4.
послать вам открытку на почту

5.
и тд.

в данном случае вы использовали ассоциативный массив.
для него стандарт гарантирует:
при удалении данных по итератору,
невалидным становится только и только тот итератор,
который смотрит на удаленный элемент.

все остальные итераторы остаются валидными,
а это значит - дерево не перестраивалось.
все объекты в контейнере сохраняют свои адреса.

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

поэтому, считайте, что вам просто не повезло:
программа в условиях UB иногда сохраняет работоспособность.
Yandex
Объявления
19.09.2015, 16:43     Почему нет ошибок?
Ответ Создать тему
Опции темы

Текущее время: 14:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru