0 / 0 / 0
Регистрация: 07.06.2014
Сообщений: 6
1

Вылет программы на деструкторе

28.09.2014, 11:34. Показов 1219. Ответов 8
Метки нет (Все метки)

Здравствуйте, подскажите пожалуйста что не так? Программа не корректно завершается
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
#pragma once
#pragma warning(disable:4996)
#include <iostream> 
using std::ostream;
using std::istream;
 
class  String
{
private:
    char*str;//Указатель на строку
    int len;//Длина строки
    static int num_strings;//Количество объектов
    static const int CINLIM = 80;//Предел ввода для cin
public:
    //Конструкторы и другие методы
    String(const char* s);//Конструктор
    String();//Конструктор по умолчанию
    String(const String & st);//Конструктор копирования
    ~String();//Деструктор
    int Length()const{ return len; }
    //Методы перегруженных операций
    String& operator=(const String& st);
    String& operator=(const char* s);
    char& operator[](int i);
    const char& operator[](int i) const;
    //Дружественные функции перегруженных операций
    friend bool operator <(const String& st1, const String& st2);
    friend bool operator >(const String& st1, const String& st2);
    friend bool operator ==(const String& st1, const String& st2);
    friend ostream& operator <<(ostream& os, const String& st);
    friend istream& operator >>(istream& is, String& st);
    //Статическая функция
    static int HowMany();
    //перегрузка + объединения строки и объекта
    friend String& operator +(const char* s, String&st);
    //Перегрузка + объединения двух String
    String& operator+(String& st);
    //Преобразует все буквенные символы в строке в верхний регистр.
    String& stringup();
    //принимает аргумент типа char и возвращает количество раз, которое символ появляется в строке.
    int has(char ch);
    String& stringlow();
};
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
#include "String_.h"//включение <iostream>
#include <cstring> // в некоторых случаях - string.h 
using std::cin;
using std::cout;
// Инициализация статического члена класса 
int String::num_strings = 0;
//Cстатический метод
int String::HowMany()
{
    return num_strings;
}
//Методы класса
String::String(const char* s)//Создание String из C-cтроки
{
    len = std::strlen(s);//Установка размера
    str = new char[len + 1];//выделение памяти
    std::strcpy(str, s);//Инициализация указателя
    num_strings++;
}
String::String()//Конструктор по умолчанию
{
    len = 4;
    str = new char[1];
    str[0] = '\0';//Строка по умолчанию
    num_strings++;
}
String::String(const String& st)//Конструктор копирования
{
    num_strings++;//Обработка обновленя статического члена
    len = st.len;//Длина та же
    str = new char[len + 1];//Выделение памяти
    std::strcpy(str, st.str);//Копирование строки в новое место
}
String::~String()//Необходимый деструктор
{
    num_strings--;//Требуется
    delete[] str;
}
//Методы перегруженных операций
//Присваивание объекта String объекту String
String& String::operator=(const String& st)
{
    if (this == &st)
        return *this;
    delete[] str;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
    return *this;
}
//Присваивание С-строки объекту String
String& String::operator=(const char* s)
{
    delete[] str;
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    return *this;
}
//Доступ для чтения и записи отдельных символов в неконстантном объекте String
char& String::operator[](int i)
{
    return str[i];
}
//Доступ только для чтения отдельных символов в константном объекте String
const char& String::operator[](int i) const
{
    return str[i];
}
//Дружественные функции перегруженных операций
bool operator<(const String& st1, const String& st2)
{
    return (std::strcmp(st1.str, st2.str) < 0);
}
bool operator>(const String& st1, const String& st2)
{
    return st2.str < st1.str;
}
bool operator==(const String& st1, const String& st2)
{
    return(std::strcmp(st1.str, st2.str) == 0);
}
//Простой вывод String
ostream& operator<<(ostream& os, const String& st)
{
    os << st.str;
    return os;
}
//Простой ввод String
istream& operator>>(istream& is, String& st)
{
    char temp[String::CINLIM];
    is.get(temp, String::CINLIM);
    if (is)
        st = temp;
    while (is&&is.get() != '\n')
        continue;
    return is;
}
String& operator +(const char* s, String&st)
{
    String tmp(st);
    st = s;
    strcat(st.str, tmp.str);
    st.len += strlen(tmp.str);
    return st;
}
String& String::operator+(String& st)
{
    strcat(str, st.str);
    len += strlen(st.str);
    return *this;
}
String& String::stringup()
{
    String tmp(str);
    for (int i = 0; i < tmp.Length();i++)
    {
        str[i] = toupper(tmp.str[i]);
    }
    return *this;
}
int String::has(char ch)
{
    int res = 0;
    for (int i = 0; i < Length(); i++)
    {
        if (ch==str[i])
        {
            res++;
        }
    }
    return res;
}
String& String::stringlow()
{
    String tmp(str);
    for (int i = 0; i < tmp.Length(); i++)
    {
        str[i] = tolower(tmp.str[i]);
    }
    return *this;
}
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
#include <iostream> 
using namespace std;
#include "String_.h" 
int main()
{
    String s1(" and I am a C++ student.");
    String s2 = "Please enter your name: "; // ввод имени 
    String s3;
    cout << s2; // перегруженная операция << 
    cin >> s3; // перегруженная операция >> 
    s2 = "My name is " + s3; // перегруженные операции =, + 
    cout<< s2 << ".\n";
    s2 = s2 + s1; 
    s2.stringup(); // преобразование строки в верхний регистр 
    cout << "The string\n" << s2 << "\ncontains " << s2.has('A')
        << " 'A' characters in it.\n";
    s1 = "red"; // String(const char *) , 
    // тогда String & operator= (const Strings) 
    String rgb[3] = { String(s1), String("green"), String("blue") };
    cout << "Enter the name of a primary color for mixing light: "; // ввод цвета 
    String ans;
    bool success = false;
    while (cin >> ans)
    {
    ans.stringlow(); // преобразование строки в нижний регистр 
        for (int i = 0; i < 3; i ++)
        {
            if (ans == rgb[i]) // перегруженная операция == 
            {
                cout << "That's right!\n";
                success = true;
                break;
            }
        }
        if (success)
            break;
        else
            cout << "Try again! \n";
    }
    cout << "Bye\n";
    return 0;
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.09.2014, 11:34
Ответы с готовыми решениями:

Вылет из программы при выполнении
Вот ф-ция из-за которой вылетает программа.Ф-ция считает среднее арифметическое соседних элементов...

Вылет программы после завершения
Добрый день. Сегодня решил начать изучение языка программирования. Нашел учебник для чайников, там...

Вылет программы с классом своего стека
Здравствуйте. Вот начинаю изучать ООП и надо написать стек. Набросал чуток кода, написал push() и...

Вылет программы при создании объекта
Начал изучать классы с создания класса для работы с массивами, класс должен работать как с...

8
Don't worry, be happy
17758 / 10526 / 2030
Регистрация: 27.09.2012
Сообщений: 26,502
Записей в блоге: 1
28.09.2014, 12:02 2
C++
1
2
3
4
5
6
7
String::String()//Конструктор по умолчанию
{
    len = 4;
    str = new char[1];
    str[0] = '\0';//Строка по умолчанию
    num_strings++;
}
почему len = 4 ?
0
5488 / 4883 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
28.09.2014, 12:08 3
Лучший ответ Сообщение было отмечено VitalikFreeMan как решение

Решение

Цитата Сообщение от VitalikFreeMan Посмотреть сообщение
C++
1
2
3
4
5
6
String& String::operator+(String& st)
{
    strcat(str, st.str);
    len += strlen(st.str);
    return *this;
}
Размер строки str достаточен, чтобы туда поместилась и строка st.str?
1
3657 / 2994 / 828
Регистрация: 25.03.2012
Сообщений: 11,031
Записей в блоге: 1
28.09.2014, 12:15 4
alsav22, однозначно нет
0
0 / 0 / 0
Регистрация: 07.06.2014
Сообщений: 6
29.09.2014, 16:02  [ТС] 5
Исправил функцию,
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
#include "String_.h"//включение <iostream>
#include <cstring> // в некоторых случаях - string.h 
using std::cin;
using std::cout;
// Инициализация статического члена класса 
int String::num_strings = 0;
//Cтатический метод
int String::HowMany()
{
    return num_strings;
}
//Методы класса
String::String(const char* s)//Создание String из C-cтроки
{
    len = std::strlen(s);//Установка размера
    str = new char[len + 1];//выдиление памяти
    std::strcpy(str, s);//Инициализация указателя
    num_strings++;
}
String::String()//Конструктор по умолчанию
{
    len = 4;
    str = new char[1];
    str[0] = '\0';//Строка по умолчанию
    num_strings++;
}
String::String(const String& st)//Конструктор копирования
{
    num_strings++;//Оброботка обновлени статического члена
    len = st.len;//Длина та же
    str = new char[len + 1];//Выделение памяти
    std::strcpy(str, st.str);//Копирование строки в новое место
}
String::~String()//Необходимый деструктор
{
    num_strings--;//Требуеться
    delete[] str;
}
//Методы перегруженных операций
//Присваивание объекта String обьекту String
String& String::operator=(const String& st)
{
    if (this == &st)
        return *this;
    delete[] str;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
    return *this;
}
//Присваение С-строки объекту String
String& String::operator=(const char* s)
{
    delete[] str;
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    return *this;
}
//Доступ для чтения и записи отдельных символов в неконстантном объекте String
char& String::operator[](int i)
{
    return str[i];
}
//Доступ только для чтения отдельных символов в константном объекте String
const char& String::operator[](int i) const
{
    return str[i];
}
//Дружественные функции перегруженных операций
bool operator<(const String& st1, const String& st2)
{
    return (std::strcmp(st1.str, st2.str) < 0);
}
bool operator>(const String& st1, const String& st2)
{
    return st2.str < st1.str;
}
bool operator==(const String& st1, const String& st2)
{
    return(std::strcmp(st1.str, st2.str) == 0);
}
//Простой вывод String
ostream& operator<<(ostream& os, const String& st)
{
    os << st.str;
    return os;
}
//Простой ввод String
istream& operator>>(istream& is, String& st)
{
    char temp[String::CINLIM];
    is.get(temp, String::CINLIM);
    if (is)
        st = temp;
    while (is&&is.get() != '\n')
        continue;
    return is;
}
String& operator +(const char* s, String&st)
{
    st.len = strlen(st.str) + strlen(s);
    char* tmp = new char[st.len + 1];
    strcpy(tmp, s);
    strcat(tmp, st.str);
    strcpy(st.str, tmp);
    delete[] tmp;
    return st;
}
String& String::operator+(String& st)
{
    len = strlen(st.str)+strlen(str);
    char* tmp = new char[len + 1];
    strcpy(tmp, str);
    strcat(tmp, st.str);
    strcpy(str, tmp);
    delete[] tmp;
    return *this;
}
String& String::stringup()
{
    String tmp(str);
    for (int i = 0; i < tmp.Length();i++)
    {
        str[i] = toupper(tmp.str[i]);
    }
    return *this;
}
int String::has(char ch)
{
    int res = 0;
    for (int i = 0; i < Length(); i++)
    {
        if (ch==str[i])
        {
            res++;
        }
    }
    return res;
}
String& String::stringlow()
{
    String tmp(str);
    for (int i = 0; i < tmp.Length(); i++)
    {
        str[i] = tolower(tmp.str[i]);
    }
    return *this;
}
но ситуацию это не исправило, в конце работы происходит аварийное закрытие программы. Не могу понять в чем проблема.
0
5488 / 4883 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
29.09.2014, 16:58 6
Лучший ответ Сообщение было отмечено VitalikFreeMan как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
String& operator +(const char* s, String&st)
{
    st.len = strlen(st.str) + strlen(s);
    char* tmp = new char[st.len + 1];
    strcpy(tmp, s);
    strcat(tmp, st.str);
    strcpy(st.str, tmp); // величина строки st.str достаточна, чтобы туда поместилась строка tmp?
    delete[] tmp;
    return st;
}
Добавлено через 3 минуты
Тут то же самое:
C++
1
2
3
4
5
6
7
8
9
10
String& String::operator+(String& st)
{
    len = strlen(st.str)+strlen(str);
    char* tmp = new char[len + 1];
    strcpy(tmp, str);
    strcat(tmp, st.str);
    strcpy(str, tmp); // ???
    delete[] tmp;
    return *this;
}
Добавлено через 4 минуты
Не нужно там копирования. Память под st.str (str) освобождайте и присваивайте str.st (str) tmp.
1
0 / 0 / 0
Регистрация: 07.06.2014
Сообщений: 6
29.09.2014, 17:22  [ТС] 7
alsav22, Спасибо, совсем забыл про выделение новой памяти.
0
5488 / 4883 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
29.09.2014, 17:50 8
Лучший ответ Сообщение было отмечено VitalikFreeMan как решение

Решение

Цитата Сообщение от VitalikFreeMan Посмотреть сообщение
Спасибо, совсем забыл про выделение новой памяти.
Это прочитали? Память выделена, просто ею нужно правильно распорядиться.
Цитата Сообщение от alsav22 Посмотреть сообщение
Не нужно там копирования. Память под st.str (str) освобождайте и присваивайте str.st (str) tmp.
Добавлено через 7 минут
Но эти операторы не совсем хорошо перегружены. Хорошая перегрузка для класса должна работать аналогично оператору для встроенных типов, а там операнды при сложении не меняются.

Добавлено через 19 минут
Как-то так:
C++
1
2
3
4
5
6
7
8
9
10
const String String::operator+(const String& st)
{
    String tmp;
    delete [] tmp.str;
    tmp.len = strlen(st.str) + strlen(str);
    tmp.str = new char[len + 1];
    strcpy(tmp.str, str);
    strcat(tmp.str, st.str);
    return tmp;
}
1
0 / 0 / 0
Регистрация: 07.06.2014
Сообщений: 6
30.09.2014, 13:02  [ТС] 9
alsav22,
Цитата Сообщение от alsav22 Посмотреть сообщение
Не нужно там копирования. Память под st.str (str) освобождайте и присваивайте str.st (str) tmp.
Это все прояснило.

Добавлено через 18 минут
Цитата Сообщение от alsav22 Посмотреть сообщение
Но эти операторы не совсем хорошо перегружены. Хорошая перегрузка для класса должна работать аналогично оператору для встроенных типов, а там операнды при сложении не меняются.
Спасибо за поправку, исправил.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.09.2014, 13:02
Помогаю со студенческими работами здесь

Вылет программы при удалении динамического массива
Писал программу с использованием динамического массива, все компилилось нормально, но в какой-то...

Создание двумерного динамического массива (вылет из программы)
Здравствуйте. Создаю двумерный динамический массив: #include &quot;stdafx.h&quot; #include &lt;iostream&gt;...

Вылет при работе программы с неизвестной ошибкой
#include &lt;iostream&gt; #include &lt;cstring&gt; using namespace std; int main() { int x=0; //...

Вылет программы без error-ов и warrning-ов. Класс матриц
Здравствуйте. Никак не могу найти причину вылета ошибки моей программы, связанной с перегрузкой +....


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru