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

Подвисание программы - C++

Восстановить пароль Регистрация
 
Runa
 Аватар для Runa
130 / 82 / 3
Регистрация: 28.08.2009
Сообщений: 363
28.12.2010, 07:13     Подвисание программы #1
Програма для создания списка, здесь приведен минимальный код воспроизводящий ошибку.
После окончания выполнения функции main программа зависает (может быть не отрабатывает деструктор)
Если убрать вызов функции AddHead то все нормально работает
Никак не могу поймать ошибку ((
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
class Books
{
public:
    long kod;
    char* avtor;
    char* name;
    long pages;
 
public:
 
    Books()
    {
        avtor = new char[100];
        name = new char[100];
    }
    void Input()
    {
        cin >> name;
        cin >> avtor;
        cin >> kod;
        cin >> pages;
    }
 
    void Output()
    {
        cout <<"\n";
        cout <<name<<"\n";
        cout <<avtor<<"\n";
        cout <<kod<<"\n";
        cout << pages<<"\n";
    }
 
    ~Books()
    {
        delete[] avtor;
        delete[] name;
    }
};
//
struct Elem
{
   Books data;
   Elem* next, * prev;
};
//
class List
{
   Elem* Head, * Tail;
   int Count;
public:
   List()
   {
       Head = Tail = 0;
       Count = 0;
   }
 
   ~List()
   {
       DelAll();
   }
 
   int GetCount()
   {
       return Count;
   }
 
   void DelAll()
   {
       while(Count != 0)
            Del(1);
   }
 
   void Del(int n)
   {
       
       int i = 1;
       Elem * Del = Head;   
       while(i < n)
       {
          Del = Del->next;
          i++;
       }
       Elem * PrevDel = Del->prev;
       Elem * AfterDel = Del->next;
       if(PrevDel != 0 && Count != 1)
          PrevDel->next = AfterDel; 
       if(AfterDel != 0 && Count != 1)
          AfterDel->prev = PrevDel;
       if(n == 1)
          Head = AfterDel;
       if(n == Count)
          Tail = PrevDel;
       delete Del;
       Count--;
   }
 
   void AddHead(Books n)
   {
       Elem * temp = new Elem;
       temp->prev = 0;
       for(int i = 0; i<10; i++)
            temp->data.avtor[i] = n.avtor[i];
       for(int i = 0; i<10; i++)
            temp->data.name[i] = n.name[i];
       temp->data.kod = n.kod;
       temp->data.pages = n.pages;
       temp->next = Head;
       if(Head != 0)
          Head->prev = temp;
       if(Count == 0)
          Head = Tail = temp;
       else
          Head = temp;
       Count++;
   }
  
};
 
int _tmain(int argc, _TCHAR* argv[])
{
 
    setlocale( LC_ALL,"Russian" );
 
    List L;
    Books b(10,10);
    b.Input();
    L.AddHead(b);
 
    L.DelAll();
    getch();
    return 0;
}
Добавлено через 1 час 15 минут
если написать вот так
C++
1
2
3
4
5
6
7
8
List L;
 
{
    Books b(100,100);
    b.Input();
    // добавление элемента в начало списка
    L.AddHead(b);
}
то на закрывающей фигурной скобке он и повисает, следовательно зависает на удалении объекта b
но почему?

Добавлено через 57 минут
не поняла почему, но проблема решилась
созданием динамического объекта вместо статического
C++
1
2
3
4
       Books *b;
    b = new Books(100,100);
    b->Input();
    L.AddHead(*b);
Может быть кто-нибудь знает почему так?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.12.2010, 07:13     Подвисание программы
Посмотрите здесь:

C++ Подскажите. Не компилирует текст программы, запрашивает в коде мол не достающую скобку. Ниже приведен текст программы.
C++ Дан текст программы на С++...Записать в выходной файл текст программы без комментариев
Открытие файла другой программы из программы.Косяк. C++
Прокомментировать код C++
Определить количество цифр в числе и их сумму C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
28.12.2010, 10:10     Подвисание программы #2
Maruna, Очищаете память то после выделения в мейне?
Runa
 Аватар для Runa
130 / 82 / 3
Регистрация: 28.08.2009
Сообщений: 363
28.12.2010, 15:02  [ТС]     Подвисание программы #3
ничего не очищаю, объекты статические, деструктор вызывается при окончании области действия
а если динамически, как во втором случае, то памать очищается нормально и нет никаких ошибок
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
28.12.2010, 15:03     Подвисание программы #4
Maruna, Написали что с динамикой все нормуль. А память очищаете? Если нет - то понятно, что все нормуль. Если да - то странно. Либо идет выход за пределы где-то, либо что-то еще более веселое.
rangerx
1908 / 1517 / 139
Регистрация: 31.05.2009
Сообщений: 2,876
28.12.2010, 15:42     Подвисание программы #5
C++
1
 L.AddHead(b);
вызовет конструктор копирования класса Books.
Runa
 Аватар для Runa
130 / 82 / 3
Регистрация: 28.08.2009
Сообщений: 363
28.12.2010, 16:50  [ТС]     Подвисание программы #6
rangerx, вы хотите сказать, что когда я передаю объект в функцию, то передаю ссылку на этот объект?

Добавлено через 2 минуты
ForEveR, да все нормально удаляю
C++
1
    delete b;
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
28.12.2010, 17:07     Подвисание программы #7
Maruna, в AddHead() будет передана копия объекта, после завершения ф-ции вызовется деструктор, который освободит память
C++
1
2
3
4
5
 Books()
        {
                avtor = new char[100];
                name = new char[100];
        }
а потом в main'е будет опять вызван деструктор, который попытается освободить уже освобожденную память, что и похоже приводит к "подвисанию".

Добавлено через 1 минуту
Так, что либо напишите конструктор копирования, либо пользуйтесь 2м вариантом (с указателем).
rangerx
1908 / 1517 / 139
Регистрация: 31.05.2009
Сообщений: 2,876
28.12.2010, 18:21     Подвисание программы #8
Цитата Сообщение от Maruna Посмотреть сообщение
вы хотите сказать, что когда я передаю объект в функцию, то передаю ссылку на этот объект?
Я хочу сказать, что когда вы делаете так
C++
1
L.AddHead(b);
а AddHead, напомню, имеет вид void AddHead(Books n)
то происходит следующее(см. комментарий)
L.AddHead(b); // Books n(b);
Т.е. для объекта n класса Books вызывается конструктор принимающий в качестве параметра ссылку на объект класса Books. Такого конструктора у вас нет, поэтому компилятор сам создаст подобный конструктор, который полностью скопирует всё содержимое объекта b в объект n, а это значит, что и указатели объекта n теперь будут указывать на ту же область памяти, что и указатели объекта b. Поэтому когда объект n выйдет из области видимости(а произойдёт это как только отработает метод AddHead) и будет вызван его деструктор, память на которую указывают указатели объекта n( и b) освободится. А когда в свою очередь будет вызван деcтруктор объекта b, то он попытается освободить память, которую уже освободил деструктор объекта n. Ничего хорошего из этого естественно не выйдет. Так вот, цель написания конструктора копирования как раз и состоит в том чтобы не допустить подобной ситуации(когда указатели разных объектов указывают на одну и ту же область памяти).
Цитата Сообщение от Kastaneda Посмотреть сообщение
Так, что либо напишите конструктор копирования,
Не "либо", а обязательно + оператор присваивания.
Цитата Сообщение от Kastaneda Посмотреть сообщение
либо пользуйтесь 2м вариантом (с указателем).
А разница-то в чём, указатель разыменованый передётся.
Runa
 Аватар для Runa
130 / 82 / 3
Регистрация: 28.08.2009
Сообщений: 363
29.12.2010, 00:35  [ТС]     Подвисание программы #9
rangerx, огромное спасибо, все очень доходчиво объяснили!
Yandex
Объявления
29.12.2010, 00:35     Подвисание программы
Ответ Создать тему
Опции темы

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