Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
0 / 0 / 0
Регистрация: 20.01.2019
Сообщений: 12
1

Проблема с STL контейнером list

20.01.2019, 13:33. Показов 1381. Ответов 8

Author24 — интернет-сервис помощи студентам
Добрый день, столкнулся с проблемой при решении учебной задачи.

Задача: "Используя приведенное ниже описание массива ia, скопируйте его содержимое в вектор и в список.
Используя версию функции erase() для одного итератора, удалите из списка элементы с нечетными значениями, а из вектора - с четными.
int ia[] = {0,1,1,2,3,5,8,13,21,55,89};

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <vector>
#include <list>
 
using std::cout;
using std::endl;
using std::vector;
using std::list;
 
int main(int argc, char const *argv[])
{
    //создание массива
    int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};
    int sizeArr = sizeof(ia)/sizeof(int);
    
    //создание вектора
    vector<int> iaVec(sizeArr);
    vector<int>::iterator iterV= iaVec.begin();
 
    //создание списка
    list<int> iaList(sizeArr);
    list<int>::iterator iterL = iaList.begin();
 
    //заполнение вектора
    for(int i = 0; i != sizeArr; ++i) {
        *iterV = ia[i];
        ++iterV;
    }
 
    //заполнение списка
    for(int i = 0; i != sizeArr; ++i) {
        *iterL = ia[i];
        ++iterL;
    }
 
    //обработка вектора
    for(vector<int>::iterator iterV = iaVec.begin(); iterV != iaVec.end();) {
        if(*iterV % 2) {
            ++iterV;
        } else {
            iaVec.erase(iterV);
        }
    }
 
    //вывод результата обработки вектора
    for(vector<int>::iterator iterV= iaVec.begin(); iterV != iaVec.end(); ++iterV) {
        cout << "Vec: " << *iterV << endl;
    }
 
    //обработка списка
    for(list<int>::iterator iterL = iaList.begin(); iterL != iaList.end();) {
        if(*iterL % 2) {
            //iaList.erase(iterL);
        } else {
            ++iterL;
        }
    }
    
    //вывод результата обработки списка
    for(list<int>::iterator iterL= iaList.begin(); iterL != iaList.end(); ++iterL) {
        cout << "List: " << *iterL << endl;
    }
 
    return 0;
}
Компиляция проходит успешно.
Обработка и вывод результата вектора проходит так же успешно.
Но когда дело доходит до обработки списка то появляется ошибка:
Bash
1
Segmentation fault (core dumped)
Не пойму в чём дело. Проверил работу iaList.erase() в не цикла, всё работает без ошибок.

Компилировал с помощью gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04).
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.01.2019, 13:33
Ответы с готовыми решениями:

Работа с контейнером библиотеки STL
Помогите реализовать программу на с++ 2010 года , не понимаю , как это делать . Задание на...

Создание обертки над контейнером stl
Добрый день. Мне нужно реализовать обертку над контейнером либо map либо set. Скажем попытка...

Работа с STL list + пропись List.h
Здравствуйте! Помогите, пожалуйста, разобраться с STL list. Нужно сделать программу в которой...

STL list
как вставить элемент в середину списка list STL? float list_insert_rand(int num) { srand...

8
447 / 333 / 172
Регистрация: 01.07.2015
Сообщений: 1,162
20.01.2019, 20:32 2
Цитата Сообщение от kavars Посмотреть сообщение
for(vector<int>::iterator iterV = iaVec.begin(); iterV != iaVec.end() {
if(*iterV % 2) {
++iterV;
} else {
iaVec.erase(iterV);
}
}
тут намудрили. Наверное, итераторы после erase не валидны
0
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
20.01.2019, 20:34 3
Лучший ответ Сообщение было отмечено kavars как решение

Решение

Цитата Сообщение от kavars Посмотреть сообщение
Используя приведенное ниже описание массива ia, скопируйте его содержимое в вектор и в список.
Используя версию функции erase() для одного итератора, удалите из списка элементы с нечетными значениями, а из вектора - с четными
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
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
 
auto print = [](const auto &cont)
{
    for (int i : cont)
        std::cout << i << ", ";
    std::cout << std::endl;
};
 
int main()
{
    const int ia[] = {0,1,1,2,3,5,8,13,21,55,89};
    std::vector<int> v{std::cbegin(ia), std::cend(ia)};
    std::list<int> l{std::cbegin(ia), std::cend(ia)};
 
    const auto isEven = [](int v) { return v % 2 == 0; };
    const auto isNotEven = [isEven](int v) { return !isEven(v); };
    v.erase(std::remove_if(v.begin(), v.end(), isEven), v.end());
    l.erase(std::remove_if(l.begin(), l.end(), isNotEven), l.end());
 
    print(v);
    print(l);
}
1
610 / 415 / 151
Регистрация: 11.01.2019
Сообщений: 1,746
20.01.2019, 20:37 4
Ну кто ж так делает??? Рубить ветку, на которой сидишь )))
erase делает итератор на удаленный элемент не валидным и ++ к нему уже нельзя применять!
1
notAll
20.01.2019, 20:42
  #5

Не по теме:

Народ, подскажите, по какой такой причине std::not1, std::not2 запрещаються к использованию?

(deprecated in C++17)
(removed in C++20

0
610 / 415 / 151
Регистрация: 11.01.2019
Сообщений: 1,746
20.01.2019, 20:45 6
Цитата Сообщение от notAll Посмотреть сообщение
Народ, подскажите, по какой такой причине std::not1, std::not2 запрещаються к использованию?
not_fn is intended to replace the C++03-era negators std::not1 and std::not2.
Вместо них появилась not_fn.
1
0 / 0 / 0
Регистрация: 20.01.2019
Сообщений: 12
20.01.2019, 22:52  [ТС] 7
jugu, Но в случае с вектором работает всё верно, почему проблема проявляется именно с list?
0
610 / 415 / 151
Регистрация: 11.01.2019
Сообщений: 1,746
20.01.2019, 22:56 8
Цитата Сообщение от kavars Посмотреть сообщение
jugu, Но в случае с вектором работает всё верно, почему проблема проявляется именно с list?
Потому что у вектора элементы идут сплошняком и положение следующего элемента известно (он соседний в памяти). А элементы списка могут быть разбросаны по памяти как угодно. Поэтому потеря итератора на удаленный элемент приводит к потере возможности найти следующий элемент списка.
1
0 / 0 / 0
Регистрация: 20.01.2019
Сообщений: 12
21.01.2019, 09:17  [ТС] 9
jugu, Спасибо большое за объяснение!
0
21.01.2019, 09:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.01.2019, 09:17
Помогаю со студенческими работами здесь

List STL
В общем нужно создать класс STL c помощью list: CStudent.h #include &lt;string&gt; using namespace...

STL list
Доброго времени суток, пока имею поверхностное представление о алгоритмах STL и функциях для...

STL List
Вот в чем проблема, была дана задача, решить которую надо было с помощью Deque и List, Deque...

Работа с STL list
Есть некий каталог с 3 переменными (string,string,int), который нужно хранить в list Как я...

STL vector,list
У меня 2 вопроса: 1) можете рассказать,как подробно работает reverse_iterator?Создал вектор,хочу...

Реализация list из STL
Можете скинуть реализацию класса list из STL.


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru