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

Наследование и связный список - C++

Восстановить пароль Регистрация
 
Laix
1 / 1 / 0
Регистрация: 15.04.2013
Сообщений: 64
17.11.2013, 20:31     Наследование и связный список #1
Пытаюсь сделать связный список, используя наследование при этом.
Есть класс Person - имя, и указатель на следующий элемент, операция копирования(чтобы не юзабельна была) и функция добавления в список - все под private, дабы не использовалось во вред. Под public - статическая переменная под голову списка(list_begin), конструктор, вирт деструктор, виртуальная функция и вспомогательные.
Далее 3 класса-наследника с переопределением виртуальной функции(show).

Программа компилируется, но на этапе выполнения после первого getch() появляется ошибка:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Error!

Program: ...aix\documents\visual studio 2012\Projects\тест\Debug\тест.exe

HEAP CORRUPTION DETECTED: after Normal block (#333) at 0x00508A58.
CRT detected that the application wrote to memory after end of heap buffer.


(Press Retry to debug the application)

---------------------------
Прервать Повтор Пропустить
---------------------------
Мой английский помог мне понять, что ошибка где то в динамическом выделении памяти, но устранить я её не смог =(.

Код программы:
Кликните здесь для просмотра всего текста
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include <iostream>
#include <conio.h>
#include <clocale>
 
using namespace std;
 
 
class Person
{
    private:
        char* name;
        Person* next;
        
        Person& operator=( const Person& ); //
        void add();
    public:     
        static Person* list_begin;
        char* getname();
    
        Person( char* );
        virtual ~Person() { delete name; }
        virtual void show() = 0;
        static void print_list();
        static void clean_list();
};
 
 
class Manager : public Person
{
    protected:
        char* work_place;
        
    public:
        Manager( char * n, char* wplace ) : Person(n)
        {
            work_place = new char[strlen(n)+1];
            strcpy( work_place, wplace );
        }
        ~Manager() { delete work_place; }
        
        void show();
};
 
class Worker : public Person
{
    protected:
        int experience;
    
    public:
        Worker( char* n, int e ) : experience(e), Person(n)
        {   }
        ~Worker() { }
        
        void show();
};
 
class Engineer : public Person
{
    protected:
        char* education;
    
    public:
        Engineer( char* n, char* edu ) : Person(n)
        {
            education = new char[strlen(edu)+1];
            strcpy( education, edu );
        }
        ~Engineer() { delete education; }
        
        void show();
};
 
 
//-------------
Person::Person(char* n)
{
    name = new char[strlen(n)+1];
    strcpy(name , n);
    next = 0;
    add();
}
 
char* Person::getname()
{
    return name;
}
 
void Person::add()
{
    if( list_begin == 0 )
            list_begin = this;
    else
        {
            Person* last = list_begin;
            while( last->next != 0 )
                last = last->next;
            last->next = this;
        }
}
 
void Person::print_list()
{
    Person* temp = list_begin;
    int i = 0;
    while( temp != 0 )
        {
            temp->show();
            i++;
            temp = temp->next;
        }
}
 
void Person::clean_list()
{
    Person* temp = list_begin;
    while( temp != 0 )
        {
            Person* deleteme = temp;
            temp = temp->next;
            delete deleteme;
        }
    list_begin = 0;
}
 
void Manager::show()
{
    cout<<"\n->Manager."<<endl;
    cout<<"  Name: "<<getname()<<endl;
    cout<<"  Work place: "<<work_place<<endl;
}
 
void Worker::show()
{
    cout<<"\n->Worker."<<endl;
    cout<<"  Name: "<<getname()<<endl;
    cout<<"  Experience: "<<experience<<endl;
}
 
void Engineer::show()
{
    cout<<"\n->Engineer."<<endl;
    cout<<"  Name: "<<getname()<<endl;
    cout<<"  Education: "<<education<<endl;
}
//----------------------------------------------------
Person* Person::list_begin = NULL;
 
int main()
{
    setlocale(LC_ALL, "rus");
    
 
    Engineer A("Александров К.Е.","Высшее");
    Manager B("Петров Е.Т.","Отдел кадров");
    Worker C("Рыбаков Е.Р.", 6);
 
    Person::print_list();
    getch();
 
    //Person::clean_list();
    //getch();
 
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
18.11.2013, 06:10     Наследование и связный список #2
C++
1
2
3
4
5
6
7
 public:
        Manager( char * n, char* wplace ) : Person(n)
        {
            work_place = new char[strlen(wplace) + 1]; // не n, а wplace
            strcpy( work_place, wplace );
        }
        ~Manager() { delete [] work_place; } // указатель на массив, поэтому нужны []
И в других деструкторах исправить на delete [].
Laix
1 / 1 / 0
Регистрация: 15.04.2013
Сообщений: 64
18.11.2013, 20:04  [ТС]     Наследование и связный список #3
alsav22, ох спасибо, вечно я с делитом конфликтую.
а скажите пожалуйста, в каких случаях требуется []delete писать? надо ли больше таких [] писать? и что происходит в моем случае если не написать?

Добавлено через 1 час 39 минут
хм... у меня теперь ошибка при вызове функции clean_list().
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!

Program: ...aix\documents\visual studio 2012\Projects\тест\Debug\тест.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)

---------------------------
Прервать Повтор Пропустить
---------------------------
Возникает она при первой же попытке удалить первый элемент(класс Engineer).
Может быть тут я пытаюсь удалить объект базового класса(Person), а он таковым не является, в следствии чего возникает ошибка? Получается организовать связный список в конструкторе базового класса не получается?

Добавлено через 14 минут
т.е. перефразирую немного вопрос: как используя виртуальный деструктор в базовом классе, удалить при этом объект производного(т.е. затронуть деструктор производного класса(напр. Engineer), вызывая только деструктор базового(Person))?
ошибка то похоже у меня из-за этого...
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
18.11.2013, 23:06     Наследование и связный список #4
Цитата Сообщение от Laix Посмотреть сообщение
в каких случаях требуется []delete писать?
Если указатель на массив. Только не [] delete, а delete [].
Laix
1 / 1 / 0
Регистрация: 15.04.2013
Сообщений: 64
18.11.2013, 23:50  [ТС]     Наследование и связный список #5
alsav22, спасибо.

Проблема решена. Объекты в мейне создал динамически и ошибка исчезла.
Yandex
Объявления
18.11.2013, 23:50     Наследование и связный список
Ответ Создать тему
Опции темы

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