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

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

Восстановить пароль Регистрация
 
tramp_1-3
 Аватар для tramp_1-3
14 / 14 / 1
Регистрация: 13.10.2012
Сообщений: 428
20.04.2013, 07:25     Ошибка в конструкторе копирования класса #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
#include <iostream>
#include "cd.h"
void Bravo (const Cd & disk);
int main () {
    Cd c1 ("Beatles", "Capitol", 14, 35.5);
    Classic c2 = Classic ("Piano sonata in B flat, Fantasia in C", "Alfred Brendel", "Phillips", 2, 57.17);
    Cd *pcd = &c1;
    using std::cout;
    Cd ad;
    ad = c1;
    cout << "Using object directly:\n";
    c1.Report ();
    cout << '\n';
    c2.Report ();
    cout << "\nUsing type cd * pointer to objects:\n";
    pcd->Report ();
    pcd = &c2;
    pcd->Report ();
    cout << "\nCalling a function with a Cd reference argument:\n";
    Bravo (c1);
    Bravo (c2);
    cout << "\nTesting assignment: ";
    Classic copy;
    copy = c2;
    copy.Report ();
    std::cin.get ();
    return 0;
};
void Bravo (const Cd & disk) {
    disk.Report ();
};

хэдэр
Кликните здесь для просмотра всего текста
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
 class Cd {
 private:
     char * performers;
     char * label;
     int length;
     int selections;
     double playtime;
 public:
     Cd (char * s1, char * s2, int n, double x);
     Cd (const Cd & d);
     Cd ();
     virtual ~Cd ();
     virtual void Report () const;
     Cd & operator = (const Cd  & d);
 };
 class Classic : public Cd {
 private:
     char * important;
 public:
     Classic ();
     Classic (char * im, char * s1, char * s2, int n, double x);
     Classic (char * im, Cd & temp);
     Classic (const Classic & temp);
     virtual void Report () const;
     Classic & operator = (const Classic & temp);
     virtual ~Classic ();
 };

методы
Кликните здесь для просмотра всего текста
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
#include "cd.h"
#include <iostream>
#include <cstring>
Cd::Cd () {
    performers = new char [8];
    strcpy (performers, "perfomer");
    label = new char [4];
    strcpy (label, "song");
    selections = 0;
    playtime = 0;
};
Cd::Cd (char  * s1, char * s2, int n, double x) {
    performers = new char [strlen (s1) + 1];
    strcpy (performers, s1);
    label = new char [strlen (s2) + 1];
    strcpy (label, s2);
    selections = n;
    playtime = x;
};
Cd::Cd (const Cd & d) {
    performers = new char [strlen (d.performers) + 1];
    strcpy (performers, d.performers);
    label = new char [strlen (d.label) + 1];
    strcpy (label, d.label);
    selections = d.selections;
    playtime = d.playtime;
};
void Cd::Report () const {
    using std::cout;
    cout << *performers << ", " << *label << ", " << selections << ", " << playtime;
};
Cd::~Cd () {
    delete [] performers;
    delete [] label;
};
Cd & Cd::operator= (const Cd & d) {
    if (this == &d) return *this;
    delete [] performers;
    delete [] label;
    length = strlen (d.performers);
    performers = new char [length + 1];
    strcpy (performers, d.performers);
    length = strlen (d.label);
    label = new char [length + 1];
    strcpy (label, d.label);
    selections = d.selections;
    playtime = d.playtime;
    return *this;
};
Classic::Classic () : Cd () {
    important = new char [14];
    strcpy (important, "Important song");
};
Classic::Classic (char * im, char * s1, char * s2, int n, double x) : Cd (s1, s2, n, x) {
    important = new char [strlen (im) + 1];
    strcpy (important, im);
};
Classic::Classic (char * im, Cd & temp) : Cd (temp) {
    important = new char [strlen (im) + 1];
    strcpy (important, im);
};
Classic::Classic (const Classic & temp) : Cd (temp) {
    important = new char [strlen (temp.important) + 1];
    strcpy (important, temp.important);
};
Classic & Classic::operator = (const Classic & temp) {
    if (this == &temp) return *this;
    delete [] important;
    Cd::operator= (temp);
    important = new char [strlen (temp.important) + 1];
    strcpy (important, temp.important);
    return *this;
};
Classic::~Classic () {
    delete [] important;
};
void Classic::Report () const {
    Cd::Report ();
    std::cout << ", " << important;
};

другая версия с той же ошибкой
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Cd & Cd::operator= (const Cd & d) {
    if (this == &d) return *this;
    delete [] performers;
    delete [] label;
    length = strlen (d.performers);
    performers = new char [length];
    strncpy (performers, d.performers,length);
    performers [length] = '\0';
    length = strlen (d.label);
    label = new char [length];
    strncpy (label, d.label, length);
    label [length] = '\0';
    selections = d.selections;
    playtime = d.playtime;
    return *this;
};
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11811 / 6790 / 767
Регистрация: 27.09.2012
Сообщений: 16,845
Записей в блоге: 2
Завершенные тесты: 1
20.04.2013, 08:24     Ошибка в конструкторе копирования класса #2
В операторе присваивания нет проверки указателей перед delete[] и выход за пределы массива.
tramp_1-3
 Аватар для tramp_1-3
14 / 14 / 1
Регистрация: 13.10.2012
Сообщений: 428
20.04.2013, 09:52  [ТС]     Ошибка в конструкторе копирования класса #3
Цитата Сообщение от Croessmah Посмотреть сообщение
В операторе присваивания нет проверки указателей перед delete[] и выход за пределы массива.
Как их проверять и где конкретно выход?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11811 / 6790 / 767
Регистрация: 27.09.2012
Сообщений: 16,845
Записей в блоге: 2
Завершенные тесты: 1
20.04.2013, 09:57     Ошибка в конструкторе копирования класса #4
При записи нуля в perfomers[length] у Вас выделяется length элементов, индексация с нуля, поэтому последний индекс будет length-1
tramp_1-3
 Аватар для tramp_1-3
14 / 14 / 1
Регистрация: 13.10.2012
Сообщений: 428
20.04.2013, 10:01  [ТС]     Ошибка в конструкторе копирования класса #5
Цитата Сообщение от Croessmah Посмотреть сообщение
При записи нуля в perfomers[length] у Вас выделяется length элементов, индексация с нуля, поэтому последний индекс будет length-1
Даже если выделять length + 1 элементов ничего не меняется
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11811 / 6790 / 767
Регистрация: 27.09.2012
Сообщений: 16,845
Записей в блоге: 2
Завершенные тесты: 1
20.04.2013, 10:08     Ошибка в конструкторе копирования класса #6
С label ситуация та же.
tramp_1-3
 Аватар для tramp_1-3
14 / 14 / 1
Регистрация: 13.10.2012
Сообщений: 428
20.04.2013, 10:20  [ТС]     Ошибка в конструкторе копирования класса #7
Цитата Сообщение от Croessmah Посмотреть сообщение
С label ситуация та же.
да хоть + 100 писать и там и там, ничего не изменится (проверено)
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
20.04.2013, 11:57     Ошибка в конструкторе копирования класса #8
Если так изменить, то работает без ошибок:
C++
1
2
3
4
5
6
7
8
9
Cd::Cd () 
{
    performers = new char [9];
    strcpy (performers, "perfomer");
    label = new char [5];
    strcpy (label, "song");
    selections = 0;
    playtime = 0;
}
C++
1
2
3
4
5
Classic::Classic () : Cd () 
{
    important = new char [15];
    strcpy (important, "Important song");
};
Миниатюры
Ошибка в конструкторе копирования класса  
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.04.2013, 12:45     Ошибка в конструкторе копирования класса
Еще ссылки по теме:

C++ В конструкторе копирования отцовского (_str) класса возникает некое "необработанное исключение"
Ошибка в конструкторе класса C++
C++ Указатель this в конструкторе копирования

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

Или воспользуйтесь поиском по форуму:
tramp_1-3
 Аватар для tramp_1-3
14 / 14 / 1
Регистрация: 13.10.2012
Сообщений: 428
20.04.2013, 12:45  [ТС]     Ошибка в конструкторе копирования класса #9
Цитата Сообщение от alsav22 Посмотреть сообщение
Если так изменить, то работает без ошибок:
Спасибо огромное, теперь будет наглядный пример переполнения памяти. С толку сбило то, что объекты создаются нормально и если поставить точку останова до присваивания то всё спокойно.
Yandex
Объявления
20.04.2013, 12:45     Ошибка в конструкторе копирования класса
Ответ Создать тему
Опции темы

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