Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Runa
132 / 84 / 3
Регистрация: 28.08.2009
Сообщений: 363
#1

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

28.12.2010, 07:13. Просмотров 459. Ответов 8
Метки нет (Все метки)

Програма для создания списка, здесь приведен минимальный код воспроизводящий ошибку.
После окончания выполнения функции 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);
Может быть кто-нибудь знает почему так?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.12.2010, 07:13
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Подвисание программы (C++):

Составить блок схему для программы упорядочивания чисел в массиве(код программы прилагается) - C++
#include &lt;iostream&gt; #include &lt;stdlib.h&gt; using namespace std; int main() { int N = 0; // N - количество элементов в массиве...

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

Открытие файла другой программы из программы.Косяк. - C++
Итак, есть в программе такой кусок: system(&quot;E:\\KMPlayer\\KMPlayer.exe E:\\WINDOWS\\New_year.mp3&quot;); Косяк в том, что пока песня не дойдёт...

Подскажите. Не компилирует текст программы, запрашивает в коде мол не достающую скобку. Ниже приведен текст программы. - C++
#include &lt;iostream.h&gt; unsigned int perimetr ( int a,int b); int main() { int a,b; cin &gt;&gt; a; cin &gt;&gt; b; cout &lt;&lt; &quot;perimetr=&quot;...

Не понимаю текста программы. Что будет напечатано в результате программы? И что вообще происходит в программе? - C++
class B { int x; B (int a=0) { x = a; cout « 1; } -B () { cout « 3; } }; class D : B { D (int d ) : B (d) {...

Дан текст программы на С++...Записать в выходной файл текст программы без комментариев - C++
( структуры и текстовые файлы)– Чтение данных в массив структур должно производиться из входного текстового файла. Дан текст...

8
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,545
Завершенные тесты: 3
28.12.2010, 10:10 #2
Maruna, Очищаете память то после выделения в мейне?
0
Runa
132 / 84 / 3
Регистрация: 28.08.2009
Сообщений: 363
28.12.2010, 15:02  [ТС] #3
ничего не очищаю, объекты статические, деструктор вызывается при окончании области действия
а если динамически, как во втором случае, то памать очищается нормально и нет никаких ошибок
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,545
Завершенные тесты: 3
28.12.2010, 15:03 #4
Maruna, Написали что с динамикой все нормуль. А память очищаете? Если нет - то понятно, что все нормуль. Если да - то странно. Либо идет выход за пределы где-то, либо что-то еще более веселое.
0
rangerx
1935 / 1544 / 141
Регистрация: 31.05.2009
Сообщений: 2,913
28.12.2010, 15:42 #5
C++
1
 L.AddHead(b);
вызовет конструктор копирования класса Books.
0
Runa
132 / 84 / 3
Регистрация: 28.08.2009
Сообщений: 363
28.12.2010, 16:50  [ТС] #6
rangerx, вы хотите сказать, что когда я передаю объект в функцию, то передаю ссылку на этот объект?

Добавлено через 2 минуты
ForEveR, да все нормально удаляю
C++
1
    delete b;
0
Kastaneda
Jesus loves me
Эксперт С++
4689 / 2893 / 236
Регистрация: 12.12.2009
Сообщений: 7,357
Записей в блоге: 2
Завершенные тесты: 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м вариантом (с указателем).
1
rangerx
1935 / 1544 / 141
Регистрация: 31.05.2009
Сообщений: 2,913
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м вариантом (с указателем).
А разница-то в чём, указатель разыменованый передётся.
1
Runa
132 / 84 / 3
Регистрация: 28.08.2009
Сообщений: 363
29.12.2010, 00:35  [ТС] #9
rangerx, огромное спасибо, все очень доходчиво объяснили!
0
29.12.2010, 00:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.12.2010, 00:35
Привет! Вот еще темы с ответами:

Подвисание программы - Delphi
begin for i := 1 to 169 do (FindComponent('Bit' + IntToStr(i)) as TBitBtn).Visible:= False; ...

.NET 4.x Подвисание программы при хеширование - C#
Все доброго времени суток. У меня вот такая проблема: - При обработке хэша большого по размеру файла (~500мб) , подвисает программа...

Потоки: как убрать подвисание интерфейса программы? - Delphi
Добрый день. У меня есть проблема. Никогда раньше с потоками не работал, почитал кое-что, понял мало что. Проблема в следующем: У меня...

Подвисание программы при получении html кода - C#
Всем привет. Мне надо получить html код страницы. У меня на кнопке есть код: private void button1_Click(object sender, EventArgs e) ...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru