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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.71
DigsiL
10 / 10 / 1
Регистрация: 14.01.2011
Сообщений: 113
#1

Ошибка при завершении программа. - C++

18.06.2011, 20:19. Просмотров 1772. Ответов 47
Метки нет (Все метки)

Проблема в следующим когда я создаю динамический массив объект при завершении программы вылетает ошибка не пойму в чем проблема ???
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
#include <iostream>
#include <Windows.h>
using namespace std;
class CBook
{
public:
    CBook(void);
    void Input(char *author1,char *title1);
    void Show ();
    ~CBook(void);
private:
    char *author;
    char *title;
};
CBook::CBook(void)
{
 
}
void CBook::Input(char *author1,char *title1)
{
        author=new char [strlen(author1)+1];
        strcpy(author,author1);
        title=new char [strlen(title1)+1];
        strcpy(title,title1);
 
}
void CBook::Show()
{
    cout<<"Автор:"<<author<<endl;
    cout<<"Название книги:"<<title<<endl;
}
 
CBook::~CBook(void)
{
    delete []author;    
    delete []title;
}
 
void AddBook(CBook *&book,int &size)
{
    CBook *temp=new CBook [size+=1];
    for (int i=1;i<=size-1;i++)
    {
        temp[i]=book[i];
    }
    book=new CBook [size];
    for (int i=1;i<=size-1;i++)
    {
        book[i]=temp[i];
    }
    //delete []temp;
}
void main()
{
    SetConsoleOutputCP(1251);
    SetConsoleCP(1251);
    char author[20];
    char title[20];
    int key=0;
    int size=0;
    CBook *book;
    do
    {
        cout<<"1.Добавить книгу"<<endl;
        cout<<"2.Вывести книги"<<endl;
        cout<<"0.Выход"<<endl;
        cin>>key;
        switch (key)
        {
        case 1:
            {
                cin.ignore();
                cout<<"Введите Автора:";
                cin.getline(author,20);
                cout<<"Введите название книги:";
                cin.getline(title,20);
                if (size>0)
                {
                    AddBook(book,size);
                }
                else 
                {
                    book=new CBook[size+=1];
                }
                book[size].Input(author,title);
            }break;
        case 2:
            {
                for (int i=1;i<=size;i++)
                {
                    book[i].Show();
                }
            }break;
        case 0:
            {
                exit(0);
            }break;
            delete []book;
            
        }
    
    }while(key);
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.06.2011, 20:19
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ошибка при завершении программа. (C++):

Ошибка при завершении программа. - C++
Проблема в следующим когда я создаю 3 объект case 1 и пробую после этого вывести case 2 вылетает ошибка в чем проблема ??? #include...

ошибка при завершении программы - C++
возникает ошибка при завершении программы. при чем после вывода на экран последней строчки. с чем это может быть связано?

Ошибка при завершении программы - C++
Добрый вечер! Помогите плиз, у меня после завершения программы она зависает... Методом тыка) определил что после завершения проги,...

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

Ошибка компилятора при завершении программы - C++
Я так подозреваю, что где то происходит выход за пределы массива. Хоть vector используй, хоть любую другую структуру, класс или массив,...

Ошибка "Stack around the variable 'a' was corrupted" при завершении программы - C++
Учусь создавать списки. Идея такова чтобы создать список в отдельном cpp, а пользователь имел доступ только к функциям добавления, удаления...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
18.06.2011, 22:59 #31
между 7 и 8 строкой надо добавить delete[] book;
0
DigsiL
10 / 10 / 1
Регистрация: 14.01.2011
Сообщений: 113
18.06.2011, 23:02  [ТС] #32
Цитата Сообщение от pito211 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
void AddBook(CBook *&book,int &size)
{
        CBook *temp=new CBook [++size];
        for (int i=0;i<size;i++)
        {
                temp[i]=book[i];
        }
        book=temp;
}
1) Утечка памяти
2) Функция вообще ничего не делает, точнее передислоцирует book в другой участок памяти. Смысл?
Я с тобой полностью согласен покажи как правильно сделать вот мой код
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
#include <iostream>
#include <Windows.h>
 
using namespace std;
class CBook
{
public:
    CBook(void);
    void Input(char *author1,char *title1,int ID1);
    void Show ();
    ~CBook(void);
private:
    int ID;
    char *author;
    char *title;
};
CBook::CBook(void)
{
        author=NULL;
        title=NULL;
        ID=NULL;
}
 
void CBook::Input(char *author1,char *title1,int ID1)
{
    ID=ID1;
    author=new char [strlen(author1)+1];
    strcpy(author,author1);
    title=new char [strlen(title1)+1];
    strcpy(title,title1);
 
}
void CBook::Show()
{
    cout<<"ID:"<<ID<<endl;
    cout<<"Автор:"<<author<<endl;
    cout<<"Название книги:"<<title<<endl;
}
 
CBook::~CBook(void)
{
    if(author!=NULL&&title!=NULL)
    {
        delete []author;    
        delete []title;
    }
}
 
void AddBook(CBook *&book,int &size)
{
    CBook *temp=new CBook [++size];
    for (int i=0;i<size;i++)
    {
        temp[i]=book[i];
    }
    book=temp;
 
 
}
void main()
{
    SetConsoleOutputCP(1251);
    SetConsoleCP(1251);
    char author[20];
    char title[20];
    int ID=0;
    int key=0;
    int size=0;
    CBook *book;
    do
    {
        cout<<"1.Добавить книгу"<<endl;
        cout<<"2.Вывести книги"<<endl;
        cout<<"0.Выход"<<endl;
        cin>>key;
        switch (key)
        {
        case 1:
            {
                ID+=1;
                cin.ignore();
                cout<<"Введите Автора:";
                cin.getline(author,20);
                cout<<"Введите название книги:";
                cin.getline(title,20);
                if (size>0)
                {
                    AddBook(book,size);
                }
                else 
                {
                    book=new CBook[++size];
                }
                book[size-1].Input(author,title,ID);
            }break;
        case 2:
            {
                for (int i=0;i<size;i++)
                {
                    book[i].Show();
                }
            }break;
        case 0:
            {
                delete []book;
                return;
            }break;
        }
    }while(key);
}
0
silentnuke
Android Programmer
139 / 140 / 5
Регистрация: 08.12.2010
Сообщений: 421
18.06.2011, 23:02 #33
Цитата Сообщение от pito211 Посмотреть сообщение
между 7 и 8 строкой надо добавить delete[] book;
ноу проблем, добавляйте.)
и протейстируйте, могу заранее сказать что потеряете весь список книг.)
т.к. произошло побитовое копирование полей.
тобишь title, author книг смотрят в тоже метсо где они и были раньше.
По поводу нет смысла. Это как нету, выделялелась память под новую книг+скопировались все старые.
1
no0ker
101 / 88 / 4
Регистрация: 17.12.2010
Сообщений: 416
18.06.2011, 23:04 #34
silentnuke,
тобишь title, author книг смотрят в тоже метсо где они и были раньше.
и вот тут на сцену выходит адекватное переопределение оператора "="...
0
silentnuke
Android Programmer
139 / 140 / 5
Регистрация: 08.12.2010
Сообщений: 421
18.06.2011, 23:07 #35
Цитата Сообщение от no0ker Посмотреть сообщение
silentnuke,
и вот тут на сцену выходит адекватное переопределение оператора "="...
я же давно сказал, мне лень его было писать. про адекватное переопределение оператора "=", знал изначально, но в данной ситуации можно обойтись и без него.
В данной ситуации утечки нету, ведь все эти поля удалятся при case 0)
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
18.06.2011, 23:10 #36
дык список и без delete потеряется, но это уже другой вопрос. Я обратил внимание на утечку памяти.
Вообще её обсуждать смысла нет, потому чт она сделана через жопу - в любой момент времени в массиве хранится только одна книга(последняя введённая) и куча неинициализированных
0
silentnuke
Android Programmer
139 / 140 / 5
Регистрация: 08.12.2010
Сообщений: 421
18.06.2011, 23:14 #37
Цитата Сообщение от pito211 Посмотреть сообщение
дык список и без delete потеряется, но это уже другой вопрос. Я обратил внимание на утечку памяти.
Вообще её обсуждать смысла нет, потому чт она сделана через жопу - в любой момент времени в массиве хранится только одна книга(последняя введённая) и куча неинициализированных
хотя да, вы правы. всеравно надо писать конструктор копирование, и перегружать оператор "=" )
0
no0ker
18.06.2011, 23:14
  #38

Не по теме:

silentnuke,

В данной ситуации утечки нету, ведь все эти поля удалятся при case 0)
вы имеете в виду, что ОС подчищает "хвосты"? потому что, в программе остаются участки памяти без направленных на них указателей, и удалить их не представляется возможным.
согласен, что утечка памяти, на работоспособность _данной_ программы влияет мало, но это не причина не бороться с ней.

1
silentnuke
Android Programmer
139 / 140 / 5
Регистрация: 08.12.2010
Сообщений: 421
18.06.2011, 23:20 #39
Цитата Сообщение от no0ker Посмотреть сообщение

Не по теме:

silentnuke,
вы имеете в виду, что ОС подчищает "хвосты"? потому что, в программе остаются участки памяти без направленных на них указателей, и удалить их не представляется возможным.
согласен, что утечка памяти, на работоспособность _данной_ программы влияет мало, но это не причина не бороться с ней.

нет я имел ввиду кое-что другое. щас все-таки скину версию с копиконструктором и перегруженным равно.
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
18.06.2011, 23:26 #40
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
#include "stdafx.h"
#include <iostream>
#include <stdexcept>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <string>
 
#include <iostream>
//#include <Windows.h>
 
using namespace std;
class CBook
{
public:
        CBook();
        CBook(const CBook& another);
        CBook(const string& _author, const string& _title1, const int& _ID);
 
        void Show ();
        ~CBook();
private:
        int ID;
        string author;
        string title;
};
CBook::CBook() : author(""), title(""), ID(0)
{
        
}
 
CBook::CBook(const CBook& another) : author(another.author), title(another.title), ID(another.ID)
{
        
}
 
CBook::CBook(const string& _author, const string& _title, const int& _ID) : author(_author), title(_title), ID(_ID)
{
        
}
 
 
 
void CBook::Show()
{
        cout<<"ID:"<<ID<<endl;
        cout<<"Автор:"<<author<<endl;
        cout<<"Название книги:"<<title<<endl;
}
 
CBook::~CBook(void)
{
 
}
 
 
void main()
{
        //SetConsoleOutputCP(1251);
        //SetConsoleCP(1251);
        string author;
        string title;
        int ID=0;
        int key=0;
        int size=0;
        vector<CBook> book;
        do
        {
                cout<<"1.Добавить книгу"<<endl;
                cout<<"2.Вывести книги"<<endl;
                cout<<"0.Выход"<<endl;
                cin>>key;
                switch (key)
                {
                case 1:
                        {
                                ID+=1;
                                cin.ignore();
                                cout<<"Введите Автора:";
                                cin >> author;
                                cout<<"Введите название книги:";
                                cin >> title;
                                
                                book.push_back(CBook(author, title, ID));
                        }break;
                case 2:
                        {
                            for (int i=0;i<book.size();i++)
                                {
                                        book[i].Show();
                                }
                        }break;
                case 0:
                        {
 
                                return;
                        }break;
                }
        }while(key);
}
Добавлено через 3 минуты
в с++ можно прекрасно обойтись без указателей и тем более тормозных сишных строк. Они нужны только в низкоуровневых представлениях. Есть string, vector, auto_ptr пользуйся ими! Хотя тебе безусловно полезно было бы потренироваться с указателями, потому что ты ни хрена не понимаешь чё делаешь судя по коду
1
no0ker
101 / 88 / 4
Регистрация: 17.12.2010
Сообщений: 416
20.06.2011, 19:12 #41
как вариант
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
164
165
166
167
168
169
170
#include <iostream>
#include <string.h>
#include <windows.h>
 
using namespace std;
class CBook
{
public:
        CBook (void);
        CBook (char *, char *, int);
        CBook (const CBook&);
        CBook& operator = (const CBook&);
        void clear(void);
        friend void swap (CBook&, CBook&);
        void init (char *author1, char *title1, int ID);
        void show(void);
        ~CBook(void);
private:
        int ID;
        char *author;
        char *title;
};
 
CBook::CBook(void){
        author = NULL;
        title = NULL;
        ID = 0;
}
 
CBook::CBook(char *author_, char *title_, int ID_){
        init(author_, title_, ID_);
}
 
CBook::CBook(const CBook& Other){
        init(Other.author, Other.title, Other.ID);
}
 
CBook& CBook::operator=(const CBook &Other){
        if(this!=&Other){
        CBook Tmp(Other);
        swap(*this, Tmp);
        return *this;
        //Tmp удаляется
        }
}
 
void CBook::clear(void){
        if(author!=NULL&&title!=NULL&&ID!=0)
        {
                delete[] author;
                author = NULL;
                delete[] title;
                title = NULL;
                ID = 0;
        }
}
 
void CBook::init(char *author_, char *title_, int ID_){
        ID = ID_;
        author = new char [strlen(author_)+1];
        strcpy(author, author_);
        title=new char [strlen(title_)+1];
        strcpy(title, title_);
}
 
void swap (CBook& One, CBook& Two){
        char *tmp_author, *tmp_title;
        int tmp_id;
        tmp_author = One.author;
        tmp_title = One.title;
        tmp_id = One.ID;
 
        One.author = Two.author;
        One.title = Two.title;
        One.ID = Two.ID;
 
        Two.author = tmp_author;
        Two.title = tmp_title;
        Two.ID = tmp_id;
}
 
void CBook::show(){
    if(ID!=0&&author!=NULL&&title!=NULL){
        cout<<"ID:"<<ID<<endl
            <<"Автор:"<<author<<endl
            <<"Название книги:"<<title<<endl;
    } else {
        cout<<"ID: __"<<endl
            <<"Автор: __"<<endl
            <<"Название книги: __"<<endl;
    }
}
 
CBook::~CBook(void){
        clear();
}
 
void AddBook(CBook *&book, int &size){
        CBook* temp;
        temp = new CBook [++size];
        int i;
 
        for (i=0; i<size-1; ++i){
                temp[i] = book[i];
        }
 
        delete[] book;
        book = NULL;
 
        book = new CBook[size];
 
        for (i=0; i<size-1; ++i){
              book[i] = temp[i];
        }
 
        delete[] temp;
        temp = NULL;
}
 
int main()
{
        SetConsoleOutputCP(1251);
        SetConsoleCP(1251);
        char author[20];
        char title[20];
        int ID=0;
        int key=0;
        int size=0;
        CBook *book=NULL;
        do{
                cout<<"1.Добавить книгу"<<endl
                    <<"2.Вывести книги"<<endl
                    <<"0.Выход"<<endl;
                cin>>key;
                switch (key){
                case 1:{
                                ++ID;
                                //cin.ignore();
                                cout<<"Введите Автора:";
                                //cin.getline(author,20);
                                cin>>author;
                                cout<<"Введите название книги:";
                                //cin.getline(title,20);
                                cin>>title;
                                if (size>0)
                                        AddBook(book, size);
                                else
                                        book = new CBook[++size];
 
                                book[size-1].init(author, title, ID);
                        }
                break;
 
                case 2:{
                        for (int i=0;i<size; ++i)
                                book[i].show();
                }
                break;
 
                case 0:{
                        if(book!=NULL){
                                delete[] book;
                                book = NULL;
                        }
                        return 0;
                        }
                break;
                }
        }while(true);
}
добавил копиконструктор и перегрузку оператора равно. в общем то, доработанный вариант ТС.
1
schdub
2946 / 1291 / 238
Регистрация: 19.01.2009
Сообщений: 3,395
Завершенные тесты: 1
20.06.2011, 20:42 #42
Цитата Сообщение от no0ker Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
void CBook::clear(void){
        if(author!=NULL&&title!=NULL&&ID!=0)
        {
                delete[] author;
                author = NULL;
                delete[] title;
                title = NULL;
                ID = 0;
        }
}
no0ker, зачем столько ифов? Раньше и я так писал, но ведь удаление нулевого указателя это безболезненная операция

C++
1
2
3
4
5
6
7
void CBook::clear(void) {
       delete[] author;
       author = NULL;
       delete[] title;
       title = NULL;
       ID = 0;
}
ну а если без ифов религия не позволяет, то можно и так:
C++
1
2
3
4
5
6
7
8
9
void CBook::clear(void) {
    if (ID > 0) {
       delete[] author;
       author = NULL;
       delete[] title;
       title = NULL;
       ID = 0;
    }
}
Добавлено через 4 минуты
кстати, имхо, init() должна быть если не в private, то как минимум в protected.
0
no0ker
101 / 88 / 4
Регистрация: 17.12.2010
Сообщений: 416
20.06.2011, 20:58 #43
schdub, согласен. с условиями перебор =)
у меня init() это установка свойств объекта, ума не приложу как можно его засунуть в private. как тогда устанавливать свойства уже созданного объекта? создавать временный объект конструктором инициализации и использовать '='?

Не по теме:

интересно, что вы скажете по поводу функции addbook() =)

0
schdub
2946 / 1291 / 238
Регистрация: 19.01.2009
Сообщений: 3,395
Завершенные тесты: 1
20.06.2011, 22:15 #44
Цитата Сообщение от no0ker Посмотреть сообщение
у меня init() это установка свойств объекта, ума не приложу как можно его засунуть в private
по идее, установка свойств объекта должна происходить в конструкторе (!). Когда мы конструируем объект Book, то скорее всего мы уже знаем, и автора, название и id. Если все же необходимо изменить одно из полей экземпляра данного класса, то целесообразно написать соответствующие сеттеры setTitle(), setAuthor() и setId(), ксати, геттеров в интерфейсе класса я не наблюдаю

Добавлено через 5 минут

Не по теме:

Цитата Сообщение от no0ker Посмотреть сообщение
интересно, что вы скажете по поводу функции addbook() =)
у меня произошел Stack Overflow на строке 98 при попытке распарсить выражение CBook *&book - за почти 8 лет программирования на С++ подобную конструкцию вижу впервые . Кстати, имхо целесообразнее данный аргумент назвать books.



Добавлено через 9 минут
Но самое главный недостаток init() в том, что благодаря данной функции пользователи класса могут попасть в беду из-за утечек памяти. Например:
C++
1
2
CBook book("Unknown", "Unknown title", 999);
book.init("Author", "Title", 666); // two memory leaks HERE :)
1
no0ker
101 / 88 / 4
Регистрация: 17.12.2010
Сообщений: 416
21.06.2011, 16:50 #45
целесообразно написать соответствующие сеттеры setTitle(), setAuthor() и setId(), ксати, геттеров в интерфейсе класса я не наблюдаю
а если в данном примере можно вместо трех сеттеров, оставить один setAll() - у меня он называется init(). а вместо трех геттеров - оставить один - getterAll сразу с выводом на cout (у меня это функция show() )
Но самое главный недостаток init() в том, что благодаря данной функции пользователи класса могут попасть в беду из-за утечек памяти.
а если вот так?
C++
1
2
3
4
5
6
7
8
void CBook::init(char *author_, char *title_, int ID_){
        clear(); // добавим очистку
        ID = ID_;
        author = new char [strlen(author_)+1];
        strcpy(author, author_);
        title=new char [strlen(title_)+1];
        strcpy(title, title_);
}
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.06.2011, 16:50
Привет! Вот еще темы с ответами:

Ошибка в завершении работы программы - C++
... char s1; std::cout&lt;&lt;&quot;Enter the file name\n&quot;; std::cin&gt;&gt;s1; if ((f=fopen(s1,&quot;r&quot;))==NULL) { perror(&quot;&quot;); ...

сделать при завершении - C++
господа можно ли в консольном приложении сделать так,что бы при закрытии окна(например нажатие на крестик)выводилась надпись(любая)

Закрытие именованного канала при завершении работы программы - C++
Добрый день. Пример: int main() { CreateNamedPipe(...); return 0; }

Очистка памяти при завершении работы функции, как правильно возвращать значения? - C++
Я вывел для себя 2 способа возвращать значения работы функции string Add(string a1, string a2) { string returnStr; returnStr +=...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
21.06.2011, 16:50
Ответ Создать тему
Опции темы

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