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

Ошибка в деструкторе

04.12.2016, 19:40. Показов 466. Ответов 7
Метки нет (Все метки)

Когда удаляю объект класса hotel, в деструкторе вызывается delete для поля этого объекта - динамически созданного связного списка. И программа падает. Без delete все работает хорошо. Помогите понять ошибку, пожалуйста


main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <locale>
#include "room.h"
#include "hotel.h"
#include "guest.h"
 
int main(void) {
    
    setlocale(LC_ALL, "RUS");
    Room r1(1, 123, 1, 1, 1, 1, 1);
    Room r2(2, 1234, 1, 1, 1, 1, 1);
    Hotel h1;
    h1.rooms.add(&r1);
    h1.rooms.add(&r2);
 
 
    Guest g1("Haha", "Aha", 1234);
    g1.takeRoom(&h1);
 
    system("pause");
    return 0;
};
hotel.cpp
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
#include "hotel.h";
#include "guest.h"
#include "list.h"
#include "heap.h"
 
using namespace std;
 
Hotel::Hotel() {};
 
Hotel::~Hotel()// деструктор
{ //удалить связный список из комнат
    delete &rooms;
};
 
List Hotel::freeRooms() //находит свободные комнаты
{
    Node *temp = &rooms.getHead(); //указатель, который изначально равен адресу начала списка
    List freeR; //список свободных комнат
    while (temp != NULL) //пока не встретит пустое значени
    {
            if (temp->r->getGuestRoom() == NULL) //Если комната списка не имеет жителя
            {
                freeR.add(temp->r); //Добавить эту комнату в список свободных комнат
            }
            temp = temp->next; //Указатель перемещается на следующий элемент
        };
    return freeR; 
};
 
void Hotel::showRooms() //Показать все комнаты
{
    rooms.show();
};
 
void Hotel::showRooms(List f_rooms) //Показать свободные комнаты
{
    f_rooms.show();
};
 
int Hotel::settle(Guest* g) //Заселить нового гостя. На выходе - номер комнаты, в которую он был заселен.
{
    int n; //номер комнаты,которую хочет снять гость
    List f_rooms; //свободные комнаты
    f_rooms = freeRooms(); //поиск свободных в отеле комнат
    showRooms(f_rooms); //вывод свободных комнат
    cout << "Введите номер комнаты, которую вы хотите снять: ";
    cin >> n;
    bool f = 0; //гость не заселен
    Node *temp = &rooms.getHead(); //указатель, который изначально равен адресу начала списка
    while (!f) //пока гость не заселен
    {
        if (temp->r->getN() == n) //если указывается на комнату с выбранным гостем номером
        {
            temp->r->settle(g); //заселить гостя g в комнату с номером n
            f = 1; //гость заселен
        }
        else { temp = temp->next; }; //Указатель перемещается на следующий элемент
    };
    
    return n;
};
 
void Hotel::moveOut( int n) //Выселить гостя из комнаты num
{
    bool f = 0; //гость не выселен
    Node *temp = &rooms.getHead(); //указатель, который изначально равен адресу начала списка
    while (!f) //пока гость не выселен
    {
        if (temp->r->getN() == n) //если указывается на комнату с выбранным гостем номером
        {
            temp->r->moveOut(); //выселить гостя g из комнаты с номером n
            f = 1; //гость выселен
        }
        else { temp = temp->next; }; //Указатель перемещается на следующий элемент
    };
};
hotel.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
#include "list.h"
#include "heap.h"
 
class Hotel {
    public:
        List rooms;   // связный список комнат
        Hotel();   // конструктор
        ~Hotel();  // деструктор
        List freeRooms(); //находит свободные комнаты
        void showRooms(); //показать все комнаты
        void showRooms(List); //показать свободные комнаты
        int settle(Guest*); //Заселить нового гостя. На выходе - номер комнаты, в которую он был заселен.
        void moveOut(int); //Выселить гостя из комнаты num
 
};
list.h
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
#pragma once
#include <stdio.h>
#include "room.h"
#include <iostream>
using namespace std;
 
struct Node       //Структура являющаяся звеном списка
{
    Room *r;     //Адрес этой комнаты будет добавляться в список
    Node *next; //Указатели на адреса следующей комнаты в списке
};
 
class List   //Создаем тип данных Список
{
    Node *head; //Указатель на адрес начала списка
public:
    Node getHead() { return *head; };
    List() //Конструктор
    {
        head = NULL;
    }
 
 
    void show() //Функция отображения списка на экране
    {
        Node *temp = head; //Определяем указатель, который изначально равен адресу начала списка
        while (temp != NULL) //До тех пор пока не встретит пустое значение
        {
            temp->r->showRoom();
            cout << endl; //Вывод информации о комнате
            temp = temp->next; //Указываем, что далее нам нужен следующий элемент
        }
    }
 
    void add(Room* r) //Функция добавления элементов в список
    {
        Node *temp= new Node; //Выделение памяти под новый элемент структуры
        temp->next = head; //Новый элемент указывает на голову 
        temp->r = r;//Записываем адрес новой комнаты в структуру
        head = temp; //Голова = тот элемент, что сейчас добавили, т.е. элемент добавляется в начало списка
    }
};
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.12.2016, 19:40
Ответы с готовыми решениями:

Ошибка в деструкторе
есть базовый абстрактный класс и есть производный от него: #ifndef EMPLOY_H #define EMPLOY_H ...

Ошибка в деструкторе
Программа работает без ошибок и полный её код не выкладываю. Но при выходе из программы получаю вот...

Классы - ошибка в деструкторе
У меня сейчас такое &quot;задание&quot;: опередить класс длинного целого числа (длинная арифметика), для...

Ошибка при работе delete в деструкторе
enum place { first = 1, second }; class Passanger { public: Passanger(); void Call(); ...

7
2548 / 1207 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
04.12.2016, 19:45 2
wildnothing, посчитайте количество delete и new у вас в коде, если числа не сходятся. Значит не верно всё!
0
Модератор
Эксперт С++
12095 / 9769 / 5907
Регистрация: 18.12.2011
Сообщений: 26,226
04.12.2016, 19:48 3
Вам и не нужно его удалять, т.к. Вы его не создавали по new.
Если очень хочется самому удалять, то можно делать так
C++
1
2
List* rooms;   // указатель на связный список комнат
Hotel(){rooms=new Room;}
И. кстати, я не вижу деструктора для класса List.
0
0 / 0 / 1
Регистрация: 26.10.2016
Сообщений: 130
04.12.2016, 19:53  [ТС] 4
Цитата Сообщение от zss Посмотреть сообщение
Вам и не нужно его удалять, т.к. Вы его не создавали по new.
А то что при добавлении новой комнаты каждый раз вызывается new, это не играет роли? Не нужно ничего удалять?
C++
1
2
3
4
5
6
7
void add(Room* r) //Функция добавления элементов в список
    {
        Node *temp= new Node; //Выделение памяти под новый элемент структуры
        temp->next = head; //Новый элемент указывает на голову 
        temp->r = r;//Записываем адрес новой комнаты в структуру
        head = temp; //Голова = тот элемент, что сейчас добавили, т.е. элемент добавляется в начало списка
    }
0
Модератор
Эксперт С++
12095 / 9769 / 5907
Регистрация: 18.12.2011
Сообщений: 26,226
04.12.2016, 19:56 5
Для этого надо написать деструктор в List (как я уже и говорил).
А вызовется он сам.
0
0 / 0 / 1
Регистрация: 26.10.2016
Сообщений: 130
04.12.2016, 20:00  [ТС] 6
Изначально так и было, но этот деструктор вызывал проблемы - программа тоже падала. В чем может бытьпробелма?

C++
1
2
3
4
5
6
7
8
9
    ~List() //Деструктор
    {
        while (head) //Пока по адресу на начало списка что-то есть
        {
            Node *temp = head->next; //Временная переменная для хранения адреса следующего элемента
            delete head; //Освобождаем адрес обозначающий начало
            head = temp; //Меняем адрес на следующий
        }
    }
0
2548 / 1207 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
04.12.2016, 20:02 7
wildnothing, а почему вы мое сообщение обошли стороной? Потому что я чёрный? Расист?
0
0 / 0 / 1
Регистрация: 26.10.2016
Сообщений: 130
04.12.2016, 20:07  [ТС] 8
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
а почему вы мое сообщение обошли стороной?
Ваш совет был применен на практике. Спасибо.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.12.2016, 20:07
Помогаю со студенческими работами здесь

Ошибка в деструкторе или перегрузке оператора C++ ООП
#include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;conio.h&gt; #include &lt;math.h&gt; #include...

Возникает ошибка при удалении динамического массива символов в деструкторе класса
Всем привет. Есть приватная переменная, указатель на строку wchar_t *pUAgent; В конструкторе...

При работе с free в деструкторе ошибка "Invalid address specified to RtlValidateHeap"
Доброго времени суток, господа эксперты и дамы эксперты. Объясните пожалуйста почему программа...

Ошибка при вызове деструктора (при вызове delete в деструкторе)
Не могу найти ошибку, при вызове деструктора от класса, который был создан при помощи конструктора...


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

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

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