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

Конструктор копирования не работает - C++

Восстановить пароль Регистрация
 
DigsiL
9 / 9 / 1
Регистрация: 14.01.2011
Сообщений: 113
06.07.2011, 11:20     Конструктор копирования не работает #1
Прошу вас помочь разобраться с конструктором копирования.
Проблема в следующем при вызове конструктора копирование вылетает ошибка не пойму в чем проблема.
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
#include <iostream>
#include <windows.h>
using namespace std;
struct Book
{
    char *term;
    char *definition;
};
class Dictionary
{
private:
    Book *string;
    int size;
public:
    Dictionary()
    {
        size=2;
        string=new Book [size];
        //------------------------------------------------------------------
        string[0].term=new char [strlen("Компьютер")+1];
        strcpy(string[0].term,"Компьютер");
        string[0].definition=new char [strlen("Вычислительная техника")+1];
        strcpy(string[0].definition,"Вычислительная техника");
        //------------------------------------------------------------------
        string[1].term=new char [strlen("Деньги")+1];
        strcpy(string[1].term,"Деньги");
        string[1].definition=new char [strlen("Универсальное средство обмена")+1];
        strcpy(string[1].definition,"Универсальное средство обмена");   
        //------------------------------------------------------------------
    }
    void Show ()
    {
        cout<<string[0].term<<" "<<string[0].definition<<endl;
    }
    const char* operator [](char *str)const
    {
        for (int i=0;i<size;i++)
        {
            if(stricmp(string[i].term,str)==0) 
            {
                return string[i].definition;
            }
            
        }
        return "Ошибка";
    }
    //Конструктор копирования
    Dictionary (const Dictionary & obj)
    {
        size=obj.size;
        for (int i=0;i<size;i++)
        {
            string[i].term=new char [strlen(obj.string[i].term)+1];
            strcpy(string[i].term,obj.string[i].term);
            string[i].definition=new char [strlen(obj.string[i].definition)+1];
            strcpy(string[i].definition,obj.string[i].definition);
        }
    }
    ~Dictionary()
    {
        delete []string;
    }
};
void Print (Dictionary c)
{
    c.Show();
}
void main ()
{
    SetConsoleOutputCP(1251);
    SetConsoleCP(1251);
    int size=1;
    Dictionary *dict=new Dictionary [size];
    int key;
    char string[20];
    Print(dict[0]);//Проверяю конструктор копирования
    do 
    {
        cout<<"1.Вывести"<<endl;
        cin>>key;
        switch (key)
        {
        case 1:
            {
                cin.ignore();
                cin.getline(string,20);
                cout<<dict[0][string]<<endl;
            }break;
        case 2:
            {
            
            }break;
        }
    } while (key!=0);
    delete []dict;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,217
Завершенные тесты: 1
06.07.2011, 11:29     Конструктор копирования не работает #2
а под string кто память выделять будет ?
oxotnik
 Аватар для oxotnik
1584 / 1061 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
06.07.2011, 11:31     Конструктор копирования не работает #3
надо перераспределить память под Book *string;, а не использовать дефолтный массив на 2 элемента, т.к. в копируемом объекте может их быть больше
ну и предварительно удалить что в дефолтном конструкторе насоздавалось
DigsiL
9 / 9 / 1
Регистрация: 14.01.2011
Сообщений: 113
06.07.2011, 11:33  [ТС]     Конструктор копирования не работает #4
Цитата Сообщение от oxotnik Посмотреть сообщение
надо перераспределить память под Book *string;, а не использовать дефолтный массив на 2 элемента, т.к. в копируемом объекте может их быть больше
ну и предварительно удалить что в дефолтном конструкторе насоздавалось
Вот переписал
только не пойму что удалять ???
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
    Dictionary (const Dictionary & obj)
    {
        size=obj.size;
        string=new Book [size];
        for (int i=0;i<size;i++)
        {
            string[i]=obj.string[i];
            string[i].term=new char [strlen(obj.string[i].term)+1];
            strcpy(string[i].term,obj.string[i].term);
            string[i].definition=new char [strlen(obj.string[i].definition)+1];
            strcpy(string[i].definition,obj.string[i].definition);
        }
    }
Net_Wanderer
235 / 208 / 19
Регистрация: 08.06.2011
Сообщений: 467
06.07.2011, 11:48     Конструктор копирования не работает #5
Цитата Сообщение от DigsiL Посмотреть сообщение
Вот переписал
только не пойму что удалять ???
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
    Dictionary (const Dictionary & obj)
    {
        size=obj.size;
        string=new Book [size];
        for (int i=0;i<size;i++)
        {
            string[i]=obj.string[i];
            string[i].term=new char [strlen(obj.string[i].term)+1];
            strcpy(string[i].term,obj.string[i].term);
            string[i].definition=new char [strlen(obj.string[i].definition)+1];
            strcpy(string[i].definition,obj.string[i].definition);
        }
    }
А зачем
C++
1
string[i]=obj.string[i];
у вас в Book оператор присваивания не переопределен, и присваиваться будут просто указатели. После этой строки, string[i].term и obj.string[i].term будут указывать на одну и туже область памяти, после этого вы под этот указатель еще выделяете память, хотя под него память уже была выделена в obj, таким образом происходит утечка.. Ну и с definition аналогично.
oxotnik
 Аватар для oxotnik
1584 / 1061 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
06.07.2011, 11:53     Конструктор копирования не работает #6
Цитата Сообщение от DigsiL Посмотреть сообщение
Вот переписал только не пойму что удалять ???
цикл по старому массиву string, в цикле удаляем все что внутри стуктуры, потом delete []string, потом создаем через new новый массив string с уже новым количеством элементов (пришедших от копируемого объекта) и еще один цикл по вновь созданному массиву с выделением памяти под каждый элемент структуры и копированием туда новых данных
DigsiL
9 / 9 / 1
Регистрация: 14.01.2011
Сообщений: 113
06.07.2011, 11:55  [ТС]     Конструктор копирования не работает #7
Цитата Сообщение от Net_Wanderer Посмотреть сообщение
А зачем
C++
1
string[i]=obj.string[i];
у вас в Book оператор присваивания не переопределен, и присваиваться будут просто указатели. После этой строки, string[i].term и obj.string[i].term будут указывать на одну и туже область памяти, после этого вы под этот указатель еще выделяете память, хотя под него память уже была выделена в obj, таким образом происходит утечка.. Ну и с definition аналогично.
Как я понял с ваших слов что достаточна такой записи
C++
1
2
3
4
5
6
7
8
9
    Dictionary (const Dictionary & obj)
    {
        size=obj.size;
        string=new Book [size];
        for (int i=0;i<size;i++)
        {
            string[i]=obj.string[i];
        }
    }
Если не верно напишите пример правильного конструктора
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,217
Завершенные тесты: 1
06.07.2011, 12:00     Конструктор копирования не работает #8
Цитата Сообщение от oxotnik Посмотреть сообщение
Вот переписал только не пойму что удалять ???
C++
1
2
3
4
5
6
7
8
9
        ~Dictionary()
        {
            for (int i = 0; i < size; ++i)
            {
                delete[] string[i].term;
                delete[] string[i].definition;
            }
            delete []string;
        }
Добавлено через 2 минуты
Цитата Сообщение от oxotnik Посмотреть сообщение
цикл по старому массиву string, в цикле удаляем все что внутри стуктуры, потом delete []string, потом создаем через new новый массив string с уже новым количеством элементов (пришедших от копируемого объекта)
это же конструктор копирования
Net_Wanderer
235 / 208 / 19
Регистрация: 08.06.2011
Сообщений: 467
06.07.2011, 12:16     Конструктор копирования не работает #9
Цитата Сообщение от DigsiL Посмотреть сообщение
Если не верно напишите пример правильного конструктора
Оставьте как было, только уберите string[i]=obj.string[i];
oxotnik
 Аватар для oxotnik
1584 / 1061 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
06.07.2011, 12:20     Конструктор копирования не работает #10
Цитата Сообщение от schdub Посмотреть сообщение
это же конструктор копирования
и что это меняет? надо ж под новые элементы выделять память а от старых избавляться
DigsiL
9 / 9 / 1
Регистрация: 14.01.2011
Сообщений: 113
06.07.2011, 12:29  [ТС]     Конструктор копирования не работает #11
НУ вот дописал я программу теперь у меня вопрос по поводу метода Set правильно у меня реализована программа???
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
#include <iostream>
#include <windows.h>
using namespace std;
struct Book
{
    char *term;
    char *definition;
};
class Dictionary
{
private:
    Book *string;
    int size;
public:
    Dictionary()
    {
        size=2;
        string=new Book [size];
        //------------------------------------------------------------------
        string[0].term=new char [strlen("Компьютер")+1];
        strcpy(string[0].term,"Компьютер");
        string[0].definition=new char [strlen("Вычислительная техника")+1];
        strcpy(string[0].definition,"Вычислительная техника");
        //------------------------------------------------------------------
        string[1].term=new char [strlen("Деньги")+1];
        strcpy(string[1].term,"Деньги");
        string[1].definition=new char [strlen("Универсальное средство обмена")+1];
        strcpy(string[1].definition,"Универсальное средство обмена");   
        //------------------------------------------------------------------
    }
    void Show ()
    {
        cout<<string[0].term<<" "<<string[0].definition<<endl;
    }
    const char* operator [](char *str)const
    {
        for (int i=0;i<size;i++)
        {
            if(stricmp(string[i].term,str)==0) 
            {
                return string[i].definition;
            }
            
        }
        return "Ошибка";
    }
    //Конструктор копирования
    Dictionary (const Dictionary & obj)
    {
        size=obj.size;
        string=new Book [size];
        for (int i=0;i<size;i++)
        {
            string[i].term=new char [strlen(obj.string[i].term)+1];
            strcpy(string[i].term,obj.string[i].term);
            string[i].definition=new char [strlen(obj.string[i].definition)+1];
            strcpy(string[i].definition,obj.string[i].definition);
        }
    }
    void  Set (char *term,char *definition)
    {
        Book *temp=new Book [size+=1];
        for (int i=0;i<size-1;i++)
        {
            temp[i]=string[i];
        }
        string = new Book [size];
        for (int i=0;i<size;i++)
        {
            string[i]=temp[i];
            if (size==i+1)
            {
                string[i].term=new char [strlen(term)+1];
                strcpy(string[i].term,term);
                string[i].definition=new char [strlen(definition)+1];
                strcpy(string[i].definition,definition);
            }
        }
    } 
    ~Dictionary()
    {
        for (int i=0;i<size;i++)
        {
            delete string[i].term;
            delete string[i].definition;
        }
        delete []string;
    }
};
void main ()
{
    SetConsoleOutputCP(1251);
    SetConsoleCP(1251);
    int size=1;
    Dictionary *dict=new Dictionary [size];
    int key;
    char term[20];
    char definition[100];
    do 
    {
        cout<<"1.Поиск по словарю"<<endl;
        cout<<"2.Добавить термин в словарь"<<endl;
        cin>>key;
        switch (key)
        {
        case 1:
            {
                cin.ignore();
                cin.getline(term,20);
                cout<<dict[0][term]<<endl;
            }break;
        case 2:
            {
                cout<<"Введите термин:"<<endl;
                cin.ignore();
                cin.getline(term,20);
                cout<<"Введите определение:"<<endl;
                cin.getline(definition,100);
                dict[0].Set(term,definition);
            }break;
        }
    } while (key!=0);
    delete []dict;
}
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,217
Завершенные тесты: 1
06.07.2011, 12:46     Конструктор копирования не работает #12
Цитата Сообщение от oxotnik Посмотреть сообщение
от старых избавляться
т.к. конструируется новый объект: указатель string и size содержат мусор, и соответственно удалять что-либо по данному адресу будет ошибкой.

Добавлено через 1 минуту
Цитата Сообщение от DigsiL Посмотреть сообщение
метода Set правильно у меня реализована программа???
смотря что данная функция должна делать
DigsiL
9 / 9 / 1
Регистрация: 14.01.2011
Сообщений: 113
06.07.2011, 12:58  [ТС]     Конструктор копирования не работает #13
Цитата Сообщение от schdub Посмотреть сообщение
т.к. конструируется новый объект: указатель string и size содержат мусор, и соответственно удалять что-либо по данному адресу будет ошибкой.

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

смотря что данная функция должна делать
Сори метод Set у меня предоставляет возможность добавлять новые термины и описания к ним в поля string
ага заметил одну ошибку исправил
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    void  Set (char *term,char *definition)
    {
        Book *temp=new Book [size+=1];
        for (int i=0;i<size-1;i++)
        {
            temp[i]=string[i];
        }
        string = new Book [size];
        for (int i=0;i<size;i++)
        {
            string[i]=temp[i];
            if (size==i+1)
            {
                string[i].term=new char [strlen(term)+1];
                strcpy(string[i].term,term);
                string[i].definition=new char [strlen(definition)+1];
                strcpy(string[i].definition,definition);
            }
        }
        delete []temp;
    }
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,217
Завершенные тесты: 1
06.07.2011, 13:09     Конструктор копирования не работает #14
Цитата Сообщение от DigsiL Посмотреть сообщение
C++
1
void Set (char *term,char *definition)
у Вас в структуре N записей какую именно запись вы хотите изменять ?

имхо в аргументы данной функции необходимо добавить индекс изменяемого элемента:
C++
1
void Set (size_t index, const char *term, const char *definition)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.07.2011, 14:04     Конструктор копирования не работает
Еще ссылки по теме:

Как работает конструктор копирования C++
C++ не работает конструктор копирования
Как работает конструктор копирования? C++

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

Или воспользуйтесь поиском по форуму:
oxotnik
 Аватар для oxotnik
1584 / 1061 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
06.07.2011, 14:04     Конструктор копирования не работает #15
Цитата Сообщение от schdub Посмотреть сообщение
т.к. конструируется новый объект: указатель string и size содержат мусор, и соответственно удалять что-либо по данному адресу будет ошибкой.
согласен, чет не подумал об этом
Yandex
Объявления
06.07.2011, 14:04     Конструктор копирования не работает
Ответ Создать тему
Опции темы

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