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

Найти ошибку в приведенном коде - C++

Восстановить пароль Регистрация
 
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
20.01.2014, 07:26     Найти ошибку в приведенном коде #1
Windows выдает ошибку, почему ?

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
#include <iostream> 
#include <cstring> 
#include <cstdlib> 
using namespace std; 
 
class strtype 
{ 
    char *p; 
    int len; 
public: 
    strtype(char *ptr); 
    void show(); 
    ~strtype(); 
}; 
 
strtype::strtype(char *ptr) 
{ 
    len=strlen(ptr); 
    p= new char[len+1]; 
    if(!p) 
    { 
        cout << "Ошибка выделения памяти\n"; 
        exit(1); 
    } 
    strcpy(p, ptr); 
}
strtype::~strtype() 
{ 
    cout << "Освобождение памяти по адресу "<<hex<<&p<<'\n'; 
    delete [] p; 
} 
void strtype::show() 
{ 
    cout << p << " - длина: " << len; 
    cout << "\n"; 
} 
int main() 
{ 
    setlocale(LC_ALL, "Russian");
//  char *p;  //переменная не используется
    strtype s1("Первая строка "), s2("Вторая строка"); 
    s1.show(); 
    s2.show(); 
    s2 = s1; 
    s1.show(); 
    s2.show(); 
    return 0;  
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
chedman
80 / 79 / 2
Регистрация: 30.10.2013
Сообщений: 249
20.01.2014, 07:34     Найти ошибку в приведенном коде #2
http://ru.wikipedia.org/wiki/%D0%9F%...D0%B8%D0%B5%29

В общем нужен явный конструктор копирования, а создаваемый компилятором неявный констр. коп. не подходит.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11844 / 6823 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 1
20.01.2014, 07:42     Найти ошибку в приведенном коде #3
и еще:
C++
1
2
    p= new char[len+1]; //new бросает исключение и в случае ошибки выделения памяти
    if(!p) //до сюда код не дойдет
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
20.01.2014, 08:06  [ТС]     Найти ошибку в приведенном коде #4
Но при создании явного конструктора копирования срабатывает деструктр и снова ошибка...
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
#include <iostream> 
#include <cstring> 
#include <cstdlib> 
using namespace std; 
 
class strtype 
{ 
    char *p; 
    int len; 
public: 
    strtype(char *a, int b)
    {}
    strtype(char *ptr); 
    void show(); 
    ~strtype(); 
    strtype operator=( strtype p2)
    {
        p = p2.p;
        len = p2.len;
        return strtype (p, len);
    }
}; 
 
strtype::strtype(char *ptr) 
{ 
    len=strlen(ptr); 
    p= new char[len+1]; 
    if(!p) // выделение памяти будет в любом случае (из-за new), поэтому данное условие никогда не пройдет
    { 
        cout << "Ошибка выделения памяти\n"; 
        exit(1); 
    } 
    strcpy(p, ptr); 
}
strtype::~strtype() 
{ 
    cout << "Освобождение памяти по адресу "<<hex<<&p<<'\n'; 
    delete [] p; 
} 
void strtype::show() 
{ 
    cout << p << " - длина: " << len; 
    cout << "\n"; 
} 
int main() 
{ 
    setlocale(LC_ALL, "Russian");
//  char *p;  //переменная не используется
    strtype s1("Первая строка "), s2("Вторая строка"); 
    s1.show(); 
    s2.show(); 
    s2 = s1;   //конструктор копирования был задан не явно 
    s1.show(); 
    s2.show(); 
    return 0;  
}
chedman
80 / 79 / 2
Регистрация: 30.10.2013
Сообщений: 249
20.01.2014, 08:36     Найти ошибку в приведенном коде #5
нужно не оператор перегружать, а вот это определить
C++
1
strtype(strtype const& copy);
http://ru.wikipedia.org/wiki/%D0%9A%...BD%D0%B8%D1%8F

Добавлено через 11 минут
А, нет все таки оператор надо перегружать.

Добавлено через 7 минут
В данном примере все таки конструктор копирования не так уж и важен, ведь s2 уже создан к моменту присваивания.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
20.01.2014, 08:37     Найти ошибку в приведенном коде #6
Проблема скорее всего в том, что при копировании у вас копируются значения указателей при этом сама строка остается в одном экземпляре. Поэтому либо следует перегрузить оператор копирования, что бы он создавал копию строки и укзатель на нее, либо изменить код деструктора, что бы он удалял строку только если больше нет объектов с указателем на эту строку. Однако замечу, что ваш код у меня нормально компилится
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11844 / 6823 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 1
20.01.2014, 08:45     Найти ошибку в приведенном коде #7
C++
1
strtype & operator=( const strtype & p2)
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
20.01.2014, 08:57  [ТС]     Найти ошибку в приведенном коде #8
Я чего-то не понимаю ))
C++
1
2
3
4
5
strtype(strtype const& copy)
    {
          p = copy.p;
        len = copy.len;
    }
Такая же ошибка.
chedman
80 / 79 / 2
Регистрация: 30.10.2013
Сообщений: 249
20.01.2014, 08:59     Найти ошибку в приведенном коде #9
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
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
 
class strtype
{
    char *p;
    int len;
public:
    strtype(char *ptr);
    void show();
    ~strtype();
 
    void swap(strtype & b)
    {
        std::swap(len, b.len);
        std::swap(p, b.p);
    }
 
    strtype & operator = (strtype const & p)
    {
        if(this != &p)
        {
            strtype(p).swap(*this);
        }
        return *this;
    }
};
 
 
 
 
strtype::strtype(char *ptr)
{
    len=strlen(ptr);
 
    p= new char[len+1];
    if(!p)
    {
        cout << "Ошибка выделения памяти\n";
        exit(1);
    }
    strcpy(p, ptr);
}
strtype::~strtype()
{
    cout << "Освобождение памяти по адресу "<<hex<<&p<<'\n';
    delete [] p;
}
void strtype::show()
{
    cout << p << " - длина: " << len;
    cout << "\n";
}
int main()
{
    system("chcp 1251");
    //setlocale(0, "866");
//  char *p;  //переменная не используется
    strtype s1("S11"), s2("S222");
    s1.show();
    s2.show();
    s2 = s1;
    s1.show();
    s2.show();
    return 0;
}
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
20.01.2014, 09:04  [ТС]     Найти ошибку в приведенном коде #10
Все равно эта же ошибка. Пользуюсь я Microsoft VS, если что.
chedman
80 / 79 / 2
Регистрация: 30.10.2013
Сообщений: 249
20.01.2014, 09:56     Найти ошибку в приведенном коде #11
Может так
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
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
 
class strtype
{
    char *p;
    int len;
public:
    strtype(char *ptr);
    void show();
    ~strtype();
 
    void swap(strtype & b)
    {
        std::swap(len, b.len);
        std::swap(p, b.p);
    }
 
    strtype & operator = (strtype const & p)
    {
        if(this != &p)
        {
            strtype(p).swap(*this);
        }
        return *this;
    }
 
    strtype(strtype const & cp):len(cp.len), p(new char[cp.len])
    {
        std::copy(cp.p, cp.p + cp.len, p);
    }
};
 
 
strtype::strtype(char *ptr)
{
    len=strlen(ptr);
 
    p= new char[len+1];
 
    cout << "Выделение памяти " << endl;
    if(!p)
    {
        cout << "Ошибка выделения памяти\n";
        exit(1);
    }
    strcpy(p, ptr);
}
 
strtype::~strtype()
{
    cout << "Освобождение памяти по адресу "<<hex<<&p<<'\n';
    delete [] p;
}
 
void strtype::show()
{
    cout << p << " - длина: " << len;
    cout << "\n";
}
 
int main()
{
    system("chcp 1251");
    //setlocale(0, "866");
//  char *p;  //переменная не используется
    strtype s1("S11"), s2("S222");
    s1.show();
    s2.show();
    s2 = s1;
    s1.show();
    s2.show();
    return 0;
}
Добавлено через 1 минуту
на самом деле тут три раза динамически выделяется память и три деструктор вызывается.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
20.01.2014, 10:03     Найти ошибку в приведенном коде #12
Повторяю еще раз. Ошибка возникает из-за того, что вот здесь:
C++
1
    s2 = s1;
Оба указателя обоих объектов указывают на один участок памяти. При закрытии программы вызывается деструктор. Однако так как указатели объектов указывают на одну и туже память программа пытается освободить учаток памяти повторно. У Лафоре есть хороший пример по этому поводу (см. работа со строками).
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
20.01.2014, 10:11  [ТС]     Найти ошибку в приведенном коде #13
Решил проблемы так (если честно - сам не понял как) :
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
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std; 
 
class strtype {
char *p;
int len;
public:
strtype(char *ptr); 
void operator=(const strtype &str);
~strtype();
void show();
}; 
 
strtype::strtype(char *ptr)
{
    len=strlen(ptr);
    p=new char[len+1];
    if(!p)
    { 
        cout << "Ошибка выделения памяти\n"; 
        exit(1);
    }
    strcpy(p, ptr);
}
 
void strtype::operator=(const strtype &str)
{
    len=strlen(str.p);
    p=new char[len+1];
    if(!p)
    { 
        cout << "Ошибка выделения памяти\n"; 
        exit(1);
    }
    strcpy(p, str.p);
}
 
strtype::~strtype()
{
    cout << "Освобождение памяти по адресу "<<hex<<&p<<'\n';
    delete[] p;
}
 
void strtype::show()
{
    cout<<p<<" - длина: "<<len;
    cout<<"\n";
} 
 
int main()
{
setlocale(LC_ALL, "Russian");
strtype s1("Первая строка "), s2("Вторая строка");
s1.show();
s2.show();
s2 = s1; 
s1.show();
s2.show();
return 0;
}
Добавлено через 3 минуты
У меня походу комп тупит... Раз десять обновлял страницу - новых сообщений не было, а тут сразу несколько... Я понял про память, но до сих пор не понимаю почему это продолжилось после перегрузки оператора "=". Кстати, сам обучаюсь по Лафоре )))
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
20.01.2014, 10:14     Найти ошибку в приведенном коде #14
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
void strtype::operator=(const strtype &str)
{
    len=strlen(str.p);
    p=new char[len+1];
    if(!p)
    { 
        cout << "Ошибка выделения памяти\n"; 
        exit(1);
    }
    strcpy(p, str.p);
}

Вот это называется утечка памяти. Куда вы дели учаток памяти выделенный при создании объекта?
Забыли строчку:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
void strtype::operator=(const strtype &str)
{
    len=strlen(str.p);
    delete[] p;
    p=new char[len+1];
    if(!p)
    { 
        cout << "Ошибка выделения памяти\n"; 
        exit(1);
    }
    strcpy(p, str.p);
}

Кстати, сам обучаюсь по Лафоре )))
Красавчик
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.01.2014, 10:39     Найти ошибку в приведенном коде
Еще ссылки по теме:

Найти ошибку в приведенном коде C++
Найти и исправить ошибки в приведенном коде C++
Найти ошибку в приведенном коде C++

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

Или воспользуйтесь поиском по форуму:
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
20.01.2014, 10:39  [ТС]     Найти ошибку в приведенном коде #15
Всем большое спасибо! Еще одно задание и можно сдаваться!))
Yandex
Объявления
20.01.2014, 10:39     Найти ошибку в приведенном коде
Ответ Создать тему
Опции темы

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