0 / 0 / 0
Регистрация: 01.11.2020
Сообщений: 40
1

Исключение при вызове метода push_back в линейном односвязном списке

06.05.2021, 12:33. Показов 1067. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. Нужно реализовать метод пуш бэк для добавления элемента в конец списка. Реализовывать хочу через вложенный класс элемента, но при выполнении даёт исключение в 39-ой строке, функции set_val. Почему?
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>
using namespace std;
 
class Sequence {
private:
    class Element {
    private:
        double v;
        Element* next;
    public:
        Element();
        Element(double);
        void set_Next(Element*);
        Element* get_Next();
        void set_Val(double);
        double get_Val();
    };
    Element* head;
public:
    Sequence();
    Sequence(double);
 
    double get_Val(int);
    int get_Size();
 
    void push_Back(double);
    void print_List();
 
 
};
 
Sequence::Element* Sequence::Element::get_Next() {
    return next;
}
void Sequence::Element::set_Next(Element* new_Next) {
    next = new_Next;
}
void Sequence::Element::set_Val(double val) {
    v = val;
}
double Sequence::Element::get_Val() {
    return v;
}
 
Sequence::Element::Element() {
    this->v = 0;
    this->next = NULL;
}
Sequence::Element::Element(double val) {
    this->v = val;
    this->next = NULL;
}
 
Sequence::Sequence() {
    head = NULL;
}
Sequence::Sequence(double val) {
    head = new Element(val);
    head->set_Next(NULL);
}
 
double Sequence::get_Val(int index) {
    if (head == nullptr) {
        cout << "Список порожнiй" << endl;
        return 0;
    }
    int size = get_Size();
    if (index < 0 || index >= size) {
        cout << "Невiрний iндекс" << endl;
        return 0;
    }
    Element* ptr = head;
    if (index <= size / 2) {
        for (int i = 0; i < index; i++) {
            ptr = ptr->get_Next();
        }
    }
    return ptr->get_Val();
}
int Sequence::get_Size() {
    if (head == nullptr) {
        return 0;
    }
    int size = 0;
    Element* ptr = head;
    do {
        ptr = ptr->get_Next();
        size++;
    } while (ptr != NULL);
    return size;
}
 
void Sequence::push_Back(double val) {
    if (head == nullptr) {
        head = new Element(val);
        head->set_Next(NULL);
        return;
    }
    Element* e = new Element;
    e = head;
    while (e!= NULL) {
        e = e->get_Next();
    }
    e->set_Val(val);
    e->set_Next(NULL);
}
void Sequence::print_List() {
    if (head == NULL) {
        cout << "Empty!\n";
        return;
    }
    Element* e = head;
    for (int i = 0; i < this->get_Size(); i++) {
        cout << e->get_Val() << endl;
        e = e->get_Next();
    }
    cout << endl;
}
 
int main() {
    Sequence S(2);
    S.print_List();
    S.push_Back(3);
    S.print_List();
    S.push_Back(4);
    S.print_List();
    system("pause");
    return 0;
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.05.2021, 12:33
Ответы с готовыми решениями:

Ошибка исполнения при вызове метода push_back
После запуска и ввода первого элемента программа вылетает, в чём ошибка? #include&lt;bits/stdc++.h&gt;...

Меняют ли элементы в vector свои адреса при вызове метода push_back?
Допустим я определил вектор и указатель на один из его элементов: vector&lt; int &gt; v( 10 ); int* p =...

Вставка, перемещение в линейном односвязном списке
Нужно помочь со вставкой, перемещением элементов и определением количества повторов. Задача:...

Поиск предыдущего элемента в односвязном линейном списке
Функция поиска предыдущего элемента для элемента со значением x в односвязном линейном списке...

3
129 / 81 / 49
Регистрация: 10.01.2020
Сообщений: 293
06.05.2021, 12:58 2
Лучший ответ Сообщение было отмечено romcheg как решение

Решение

Пытаетесь доступиться к нулевому указателю, посерьезнее относитесь к таким вещам. Подобных ошибок в коде достаточно.
Также, в Getерах в классе Element, в вашем случае, возвращайте по ссылке(Sequence::Element*&).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Sequence::push_Back(double val)
{
    Element* newEl = new Element(val);
    if (head == nullptr) {
        head = newEl;
        head->set_Next(NULL);
        return;
    }
    Element* e = head;
    while (e->get_Next() != NULL) {
        e = e->get_Next();
    }
    e->get_Next() = newEl;
}
0
0 / 0 / 0
Регистрация: 01.11.2020
Сообщений: 40
06.05.2021, 13:18  [ТС] 3
Спасибо! Но теперь выбивает такое-же исключение в функции get_Size() (В этом коде - 87 строка), где ptr=ptr->get_Next(); Я переделал код, но не думаю, что это повлияло. Для справки - в новом коде выбивает исключение в 41 строке "нарущение доступа для чтения. ptr было 0xCDCDCDCD."
Новый код:
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
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
using namespace std;
 
struct Node {
    double v;
    Node* next;
};
class Sequence {
private:
    Node* head;
public:
    Sequence();
    Sequence(double);
    ~Sequence();
 
    int get_Size();
 
    void push_Back(double);
    void print_List();
};
Sequence::Sequence() {
    head = new Node;
    head->next = NULL;
}
Sequence::Sequence(double val) {
    head = new Node;
    head->v = val;
    head->next = NULL;
}
Sequence::~Sequence() {
    delete head;
}
 
int Sequence::get_Size() {
    if (head == nullptr) {
        return 0;
    }
    int size = 0;
    Node* ptr = head;
    do {
        ptr = ptr->next;
        size++;
    } while (ptr != NULL);
    return size;
}
 
void Sequence::print_List() {
    if (head == NULL) {
        cout << "Empty!\n";
        return;
    }
    Node* e = head;
    for (int i = 0; i < this->get_Size(); i++) {
        cout << e->v << endl;
        e = e->next;
    }
}
void Sequence::push_Back(double val) {
    Node* e = new Node;
    e->v = val;
    if (head == nullptr) {
        head = e;
        head->next = NULL;
        return;
    }
    Node* e1 = head;
    while (e1->next != NULL) {
        e1 = e1->next;
    }
    e1->next = e;
}
int main() {
    Sequence A(10.5);
    A.print_List();
    A.push_Back(2);
    A.print_List();
}
0
129 / 81 / 49
Регистрация: 10.01.2020
Сообщений: 293
06.05.2021, 13:30 4
romcheg, Сделайте лучше в классе Sequence поле size, которое будете получать и изменять при добавлении узла, чтобы не делать класс медленнее каждый раз перешагивая по всему списку.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Sequence {
private:
    Node* head;
 
    int m_iSize;
public:
    Sequence()
    {
        this->head = nullptr;
        this->m_iSize = 0;
    }
    
    /*
    .  .  .
    */
};
Добавлено через 6 минут
romcheg, да еще и учитывая, что в void Sequence:: print_List() вы при каждой итерации вызываете этот метод, так это вообще не хорошо. Ну а сама ошибка, я полагаю, опять из-за потерянных указателей, за которыми, как я говорил ранее нужно следить.
1
06.05.2021, 13:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.05.2021, 13:30
Помогаю со студенческими работами здесь

Разместить элементы файла в динамическ памяти в односвязном линейном списке
Задача. Создать файл символов.(можно в ручную на пк) Разместить элементы файла в динамической...

Написать функцию нахождения максимального значения в линейном односвязном списке
Нужно написать функцию нахождения максимального значения в линейном односвязном списке. Помогите...

Разместить элементы файла в динамической памяти в односвязном линейном списке
Задача &quot;Разместить элементы файла в динамической памяти в односвязном линейном списке. Из связного...

Как в линейном односвязном списке переставить слова в обратном порядке?
Вот программа, которая создает список и выводит его на экран: Type Ukazatel = ^S; S = Record...

Вставка нового узла перед выбранным узлом в линейном односвязном списке
Как сделать вставку нового узла перед выбранный узлом в линейном односвязном списке?

Разместить в односвязном линейном списке в динамической памяти строки, начинающиеся с согласной буквы
Решить задачу по обработке файлов данных с использованием динамической памяти (указателей):...


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

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

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