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

Сбиваются указатели при переходе между функциями - C++

Восстановить пароль Регистрация
 
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
02.07.2015, 13:01     Сбиваются указатели при переходе между функциями #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
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#include <iostream>
#include <Windows.h>
using namespace std;
 
class Polynom
{
public:
    Polynom(int power_ = 0, float *koef_ = NULL);
    Polynom(Polynom &right);
    ~Polynom();
 
    float& operator[](int idx);
    int Power();
    void SetPower(int power_);
    
    Polynom& operator=(Polynom &right);
    Polynom& operator-();
    Polynom& operator+=(Polynom &right);
    Polynom& operator-=(Polynom &right);
    Polynom& operator*=(Polynom &right);
    Polynom& operator+(Polynom &right);
    Polynom& operator-(Polynom &right);
    Polynom& operator*(Polynom &right);
 
    bool operator==(Polynom &right);
    bool operator!=(Polynom &right);
    bool operator>(Polynom &right);
    bool operator<(Polynom &right);
    bool operator>=(Polynom &right);
    bool operator<=(Polynom &right);
private:
    int power;
    float *koef;
};
 
Polynom::Polynom(int power_, float *koef_)
{
    power = power_;
    koef = new float[power+1];
    if (koef_ != NULL)
        for (int i = 0; i <= power; i++)
            koef[i] = koef_[i];
    else
        for (int i = 0; i <= power; i++)
            koef[i] = 0;
}
 
Polynom::Polynom(Polynom &right)
{
    koef = new float[1];
    *this = right;
}
 
Polynom::~Polynom()
{
    delete [] koef;
}
 
float& Polynom::operator[](int idx)
{
    if (idx < power && idx >= 0)
        return koef[idx];
    else
        return koef[power-1];
}
 
int Polynom::Power()
{
    return power;
}
 
void Polynom::SetPower(int power_)
{
    float *newkoef = new float[power_+1];
    int minpower = (power < power_? power : power_);
    for (int i = 0; i <= minpower; i++)
        newkoef[i] = koef[i];
    power = power_;
    delete [] koef;
    koef = newkoef;
}
 
ostream& operator<<(ostream &out, Polynom &p)
{
    for (int i = p.Power(); i > 0; i--)
        out << (p[i] >= 0? (i != p.Power()? " + " : "") : " - ") << abs(p[i]) << "*x^" << i;
    out << (p[0] >= 0? " + " : " - ") << p[0];
    return out;
}
 
istream& operator>>(istream &in, Polynom &p)
{
    int power;
    cout << "Введите степень многочлена: ";
    in >> power;
    p.SetPower(power);
    cout << "Введите коэффициенты при степенях от меньшей степени к большей: ";
    for (int i = 0; i <= power; i++)
        in >> p[i];
    cout << "Многочлен сохранен!\n";
    return in;
}
 
Polynom& Polynom::operator=(Polynom &right)
{
    delete [] koef;
    power = right.power;
    koef = new float[power+1];
    for (int i = 0; i <= power; i++)
        koef[i] = right[i];
    return *this;
}
 
Polynom& Polynom::operator-()
{
    Polynom res(*this);
    for (int i = 0; i <= power; i++)
        res[i] = -res[i];
    return res;
}
 
Polynom& Polynom::operator+=(Polynom &right)
{
    if (right.power > power)
    {
        float *newkoef = new float[right.power+1];
        for (int i = 0; i <= right.power; i++)
            newkoef[i] = (i <= right.power? koef[i] : 0);
        *this = Polynom(right.power, newkoef);
    }
    else
        for (int i = 0; i <= right.power; i++)
            koef[i] += right[i];
    return *this;
}
 
Polynom& Polynom::operator-=(Polynom &right)
{
    return *this += -right;
}
 
Polynom& Polynom::operator*=(Polynom &right)
{
    Polynom res(power + right.power);
    for (int i = 0; i <= power; i++)
        for (int j = 0; j <= right.power; j++)
            res[i+j] += koef[i]*right[j];
    *this = res;
    return *this;
}
 
Polynom& Polynom::operator+(Polynom &right)
{
    return (Polynom() += *this) += right;
}
 
Polynom& Polynom::operator-(Polynom &right)
{
    return (Polynom() -= *this) -= right;
}
 
Polynom& Polynom::operator*(Polynom &right)
{
    return (Polynom() *= *this) *= right;
}
 
bool Polynom::operator==(Polynom &right)
{
    if (power != right.power)
        return false;
    else
        for (int i = 0; i <= power; i++)
            if (koef[i] != right[i])
                return false;
    return true;
}
 
bool Polynom::operator!=(Polynom &right)
{
    return !(*this == right);
}
 
bool Polynom::operator<(Polynom &right)
{
    if (power != right.power)
        return power < right.power;
    else
        for (int i = 0; i <= power; i++)
            if (abs(koef[i]) < abs(right[i]))
                return true;
    return false;
}
 
bool Polynom::operator>(Polynom &right)
{
    if (power != right.power)
        return power > right.power;
    else
        for (int i = 0; i <= power; i++)
            if (abs(koef[i]) > abs(right[i]))
                return true;
    return false;
}
 
bool Polynom::operator<=(Polynom &right)
{
    return *this < right || *this == right;
}
 
bool Polynom::operator>=(Polynom &right)
{
    return *this > right || *this == right;
}
 
int main()
{
    Polynom p1, p2;
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    cout << "ПЕРВЫЙ МНОГОЧЛЕН\n";
    cin >> p1;
    cout << "ВТОРОЙ МНОГОЧЛЕН\n";
    cin >> p2;
    
    cout << "P1 = " << p1 << endl
        << "P2 = " << p2 << endl;
    cout << "P1 + P2 = " << p1 + p2 << endl
        << "P1 - P2 = " << p1 - p2 << endl
        << "P1 * P2 = " << p1 * p2 << endl;
    system("pause");
    return 0;
}
На выходе из SetPower (строка 72) указатель koef сбивается и начинает указывать на какой-то некорректный участок памяти. По крайней мере при пошаговом выполнении так показывается. Но при выводе многочлена почему-то просто немного путаются числа, и все. Помогите пожалуйста разобраться

Добавлено через 5 минут
(если что, не ругать - я болею )
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
02.07.2015, 13:03     Сбиваются указатели при переходе между функциями #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Керра, функции operator+(Polynom &), operator*(Polynom &), operator-(Polynom &), operator-() должны возвращать объект по значению. Сейчас происходит следующее: в этих функциях создается временный безымянный объект, над которым происходят изменения, и возвращается ссылка на него. Но этот объект уничтожается в конце выражения return.
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
02.07.2015, 13:05  [ТС]     Сбиваются указатели при переходе между функциями #3
Аа, блин точно. Я ж собиралась по значению и возвращать... Невнимательность... Спасибо большое)
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
02.07.2015, 13:07     Сбиваются указатели при переходе между функциями #4
C++
1
2
3
4
5
Polynom::Polynom(Polynom &right)
{
    koef = new float[1];
    *this = right;
}
Во-первых, const Polynom &right, во-вторых, че это за
C++
1
    *this = right;
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
02.07.2015, 13:11  [ТС]     Сбиваются указатели при переходе между функциями #5
Цитата Сообщение от Croessmah Посмотреть сообщение
*this = right;
Ну оператор присваивания-то у нас перегружен, так что все ок.

Хотя в таком виде снова что-то не то... Я извиняюсь за наглость, но сил моих в связи со здоровьем в ближайшие полчаса точно не появится, а надо было срочно
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#include <iostream>
#include <Windows.h>
using namespace std;
 
class Polynom
{
public:
    Polynom(int power_ = 0, float *koef_ = NULL);
    Polynom(Polynom &right);
    ~Polynom();
 
    float& operator[](int idx);
    int Power();
    void SetPower(int power_);
    
    Polynom operator=(Polynom &right);
    Polynom operator-();
    Polynom operator+=(Polynom &right);
    Polynom operator-=(Polynom &right);
    Polynom operator*=(Polynom &right);
    Polynom operator+(Polynom &right);
    Polynom operator-(Polynom &right);
    Polynom operator*(Polynom &right);
 
    bool operator==(Polynom &right);
    bool operator!=(Polynom &right);
    bool operator>(Polynom &right);
    bool operator<(Polynom &right);
    bool operator>=(Polynom &right);
    bool operator<=(Polynom &right);
private:
    int power;
    float *koef;
};
 
Polynom::Polynom(int power_, float *koef_)
{
    power = power_;
    koef = new float[power+1];
    if (koef_ != NULL)
        for (int i = 0; i <= power; i++)
            koef[i] = koef_[i];
    else
        for (int i = 0; i <= power; i++)
            koef[i] = 0;
}
 
Polynom::Polynom(Polynom &right)
{
    koef = new float[1];
    *this = right;
}
 
Polynom::~Polynom()
{
    delete [] koef;
}
 
float& Polynom::operator[](int idx)
{
    if (idx < power && idx >= 0)
        return koef[idx];
    else
        return koef[power-1];
}
 
int Polynom::Power()
{
    return power;
}
 
void Polynom::SetPower(int power_)
{
    float *newkoef = new float[power_+1];
    int minpower = (power < power_? power : power_);
    for (int i = 0; i <= minpower; i++)
        newkoef[i] = koef[i];
    power = power_;
    delete [] koef;
    koef = newkoef;
}
 
ostream& operator<<(ostream &out, Polynom &p)
{
    for (int i = p.Power(); i > 0; i--)
        out << (p[i] >= 0? (i != p.Power()? " + " : "") : " - ") << abs(p[i]) << "*x^" << i;
    out << (p[0] >= 0? " + " : " - ") << p[0];
    return out;
}
 
istream& operator>>(istream &in, Polynom &p)
{
    int power;
    cout << "Введите степень многочлена: ";
    in >> power;
    p.SetPower(power);
    cout << "Введите коэффициенты при степенях от меньшей степени к большей: ";
    for (int i = 0; i <= power; i++)
        in >> p[i];
    cout << "Многочлен сохранен!\n";
    return in;
}
 
Polynom Polynom::operator=(Polynom &right)
{
    delete [] koef;
    power = right.power;
    koef = new float[power+1];
    for (int i = 0; i <= power; i++)
        koef[i] = right[i];
    return *this;
}
 
Polynom Polynom::operator-()
{
    Polynom res(*this);
    for (int i = 0; i <= power; i++)
        res[i] = -res[i];
    return res;
}
 
Polynom Polynom::operator+=(Polynom &right)
{
    if (right.power > power)
    {
        float *newkoef = new float[right.power+1];
        for (int i = 0; i <= right.power; i++)
            newkoef[i] = (i <= right.power? koef[i] : 0);
        *this = Polynom(right.power, newkoef);
    }
    else
        for (int i = 0; i <= right.power; i++)
            koef[i] += right[i];
    return *this;
}
 
Polynom Polynom::operator-=(Polynom &right)
{
    return *this += -right;
}
 
Polynom Polynom::operator*=(Polynom &right)
{
    Polynom res(power + right.power);
    for (int i = 0; i <= power; i++)
        for (int j = 0; j <= right.power; j++)
            res[i+j] += koef[i]*right[j];
    *this = res;
    return *this;
}
 
Polynom Polynom::operator+(Polynom &right)
{
    return (Polynom() += *this) += right;
}
 
Polynom Polynom::operator-(Polynom &right)
{
    return (Polynom() -= *this) -= right;
}
 
Polynom Polynom::operator*(Polynom &right)
{
    return (Polynom() *= *this) *= right;
}
 
bool Polynom::operator==(Polynom &right)
{
    if (power != right.power)
        return false;
    else
        for (int i = 0; i <= power; i++)
            if (koef[i] != right[i])
                return false;
    return true;
}
 
bool Polynom::operator!=(Polynom &right)
{
    return !(*this == right);
}
 
bool Polynom::operator<(Polynom &right)
{
    if (power != right.power)
        return power < right.power;
    else
        for (int i = 0; i <= power; i++)
            if (abs(koef[i]) < abs(right[i]))
                return true;
    return false;
}
 
bool Polynom::operator>(Polynom &right)
{
    if (power != right.power)
        return power > right.power;
    else
        for (int i = 0; i <= power; i++)
            if (abs(koef[i]) > abs(right[i]))
                return true;
    return false;
}
 
bool Polynom::operator<=(Polynom &right)
{
    return *this < right || *this == right;
}
 
bool Polynom::operator>=(Polynom &right)
{
    return *this > right || *this == right;
}
 
int main()
{
    Polynom p1, p2;
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    cout << "ПЕРВЫЙ МНОГОЧЛЕН\n";
    cin >> p1;
    cout << "ВТОРОЙ МНОГОЧЛЕН\n";
    cin >> p2;
    
    cout << "P1 = " << p1 << endl
        << "P2 = " << p2 << endl;
    cout << "P1 + P2 = " << p1 + p2 << endl
        << "P1 - P2 = " << p1 - p2 << endl
        << "P1 * P2 = " << p1 * p2 << endl;
    system("pause");
    return 0;
}
Миниатюры
Сбиваются указатели при переходе между функциями  
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
02.07.2015, 13:12     Сбиваются указатели при переходе между функциями #6
Керра, еще было бы здорово, если бы уделялось больше внимания константности там, где это необходимо. В частности, аргументы операторных функций, если они не изменяются, лучше передавать по константной ссылке. А методы, не меняющие состояние объекта, указать как const.
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
02.07.2015, 13:13  [ТС]     Сбиваются указатели при переходе между функциями #7
Я в курсе, но пишу для студентика, а студентики так не делают, я и так с качеством обычно перебарщиваю
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
02.07.2015, 13:28     Сбиваются указатели при переходе между функциями #8
Керра, Вот такой конструктор копирования:
C++
1
2
3
4
5
6
7
Polynom::Polynom(Polynom const &right)
    : power(right.power)
    , koef(new float[power+1])
{
    for (int i = 0; i <= power; i++)
        koef[i] = right[i];
}
Вот такой оператор присваивания:
C++
1
2
3
4
5
6
7
8
Polynom & Polynom::operator=(Polynom const &right)
{
    if(&right != this)
    {
        Polynom(right).swap(*this);
    }
    return *this;
}
Функцию swap определить в private:
C++
1
2
3
4
5
    void swap(Polynom & other)
    {
        std::swap(other.power, power);
        std::swap(other.koef, koef);
    }
Добавлено через 1 минуту
Цитата Сообщение от Керра Посмотреть сообщение
Я в курсе, но пишу для студентика, а студентики так не делают, я и так с качеством обычно перебарщиваю
Может и не делают, но код получился некорректный чуть менее, чем полностью.
Программа же в первую очередь должна работать.
А если он соберется ее компилировать не в VS, то просто не сможет ее собрать. Т.к. rvalue нельзя цеплять к неконстантной ссылке.

Добавлено через 2 минуты
Цитата Сообщение от Керра Посмотреть сообщение
C++
1
2
3
4
Polynom operator=(Polynom &right);
Polynom operator+=(Polynom &right); 
Polynom operator-=(Polynom &right); 
Polynom operator*=(Polynom &right);
Здесь ссылки надо оставить. Т.к. эти операторы меняют существующий объект, а не создают новый.
xEmpire
23 / 23 / 9
Регистрация: 07.12.2012
Сообщений: 169
Завершенные тесты: 1
02.07.2015, 13:30     Сбиваются указатели при переходе между функциями #9
Керра, как это студенты так не делают?
mutable тоже?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
02.07.2015, 13:34     Сбиваются указатели при переходе между функциями #10
Цитата Сообщение от Керра Посмотреть сообщение
Ну оператор присваивания-то у нас перегружен, так что все ок.
ну будь так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Polynom::Polynom(Polynom &right)
{
    koef = new float[1]; //<-- здесь выделили
    *this = right;
}
//...
Polynom& Polynom::operator=(Polynom &right)
{
    delete [] koef; //<-- следом освободили
    power = right.power;
    koef = new float[power+1]; //Опять выделили
    for (int i = 0; i <= power; i++)
        koef[i] = right[i];
    return *this;
}
можно было сделать функцию copy_from и копировать объект в ней. Тогда:
C++
1
2
3
4
5
6
7
8
9
10
11
12
Polynom::Polynom(const Polynom &right)
{
    copy_from(right) ;
}
//...
Polynom& Polynom::operator=(const Polynom &right)
{
    if ( this == &right )
        return *this ;
    delete [] koef; 
    copy_from (right) ;
}
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
02.07.2015, 13:35  [ТС]     Сбиваются указатели при переходе между функциями #11
Цитата Сообщение от DrOffset Посмотреть сообщение
Может и не делают, но код получился некорректный чуть менее, чем полностью.
нуууууууу я тоже студентка... да и болею... ну в общем да, я совсем-совсем начинающий программист, я знаю об этом))
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
02.07.2015, 13:43     Сбиваются указатели при переходе между функциями #12
Керра, вот тебе совет, который позволит избежать подобных ошибок в будущем.
Когда пишешь такие классы (с динамически выделяемыми ресурсами), первым делом, всегда, убеждайся, что они нормально копируются и присваиваются. А только потом реализуй всю остальную функциональность.
rjxk
 Аватар для rjxk
7 / 7 / 6
Регистрация: 18.06.2015
Сообщений: 30
03.07.2015, 02:42     Сбиваются указатели при переходе между функциями #13
Цитата Сообщение от Керра Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
bool Polynom::operator==(Polynom &right)
{
* * if (power != right.power)
* * * * return false;
* * else
* * * * for (int i = 0; i <= power; i++)
* * * * * * if (koef[i] != right[i])
* * * * * * * * return false;
* * return true;
}
if (koef[i] != right[i])
ошибка сравнения. koef и right - разные типы

float *koef;
Polynom &right
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.07.2015, 06:07     Сбиваются указатели при переходе между функциями
Еще ссылки по теме:

C++ В чем разница между функциями strcat() и strcpy()?
C++ В чем разница между функциями, прототипы которых имеют вид?
Почему изменяется значение переменной между функциями класса? C++

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

Или воспользуйтесь поиском по форуму:
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
03.07.2015, 06:07     Сбиваются указатели при переходе между функциями #14
Цитата Сообщение от rjxk Посмотреть сообщение
ошибка сравнения. koef и right - разные типы
C++
1
float& operator[](int idx);
Yandex
Объявления
03.07.2015, 06:07     Сбиваются указатели при переходе между функциями
Ответ Создать тему
Опции темы

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