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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
MayaNash
1285 / 453 / 47
Регистрация: 24.08.2011
Сообщений: 2,207
#1

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

02.07.2015, 13:01. Просмотров 288. Ответов 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
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)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.07.2015, 13:01
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Сбиваются указатели при переходе между функциями (C++):

работа между функциями - C++
в функции func_1 я вычислил массив p1. Как мне использовать данные этого массива в другой функции?

Переход между функциями - C++
Как в C++ возможно осуществить переход между функциями ? goto не помогает :( Для примера : void funct1() { } void...

Функции: связь между функциями - C++
Здравствуйте уважаемые программисты! Есть задача, в которой по условию вводишь время от начала 12 часов дня до 00.00, и она должна...

В чём разница между процедурами и функциями ? - C++
Мне просто нужно будет выполнить одну и ту же операцию несколько раз, а сама операция включает в себя несколько вычислений , создание...

Передача свойств объектов между функциями - C++
Народ, I need help! Есть класс: class Employees { public: Employees(); Employees(std::string _Surname, std::string _Name,...

Разница между функциями atan и atan2 - C++
Здравствуйте. В чём разница между atan и atan2?

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
DrOffset
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
02.07.2015, 13:03 #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Керра, функции operator+(Polynom &), operator*(Polynom &), operator-(Polynom &), operator-() должны возвращать объект по значению. Сейчас происходит следующее: в этих функциях создается временный безымянный объект, над которым происходят изменения, и возвращается ссылка на него. Но этот объект уничтожается в конце выражения return.
MayaNash
1285 / 453 / 47
Регистрация: 24.08.2011
Сообщений: 2,207
02.07.2015, 13:05  [ТС] #3
Аа, блин точно. Я ж собиралась по значению и возвращать... Невнимательность... Спасибо большое)
Croessmah
Модератор
Эксперт CЭксперт С++
13135 / 7398 / 828
Регистрация: 27.09.2012
Сообщений: 18,234
Записей в блоге: 3
Завершенные тесты: 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;
MayaNash
1285 / 453 / 47
Регистрация: 24.08.2011
Сообщений: 2,207
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
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
02.07.2015, 13:12 #6
Керра, еще было бы здорово, если бы уделялось больше внимания константности там, где это необходимо. В частности, аргументы операторных функций, если они не изменяются, лучше передавать по константной ссылке. А методы, не меняющие состояние объекта, указать как const.
MayaNash
1285 / 453 / 47
Регистрация: 24.08.2011
Сообщений: 2,207
02.07.2015, 13:13  [ТС] #7
Я в курсе, но пишу для студентика, а студентики так не делают, я и так с качеством обычно перебарщиваю
DrOffset
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
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
24 / 24 / 9
Регистрация: 07.12.2012
Сообщений: 169
Завершенные тесты: 1
02.07.2015, 13:30 #9
Керра, как это студенты так не делают?
mutable тоже?
Croessmah
Модератор
Эксперт CЭксперт С++
13135 / 7398 / 828
Регистрация: 27.09.2012
Сообщений: 18,234
Записей в блоге: 3
Завершенные тесты: 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) ;
}
MayaNash
1285 / 453 / 47
Регистрация: 24.08.2011
Сообщений: 2,207
02.07.2015, 13:35  [ТС] #11
Цитата Сообщение от DrOffset Посмотреть сообщение
Может и не делают, но код получился некорректный чуть менее, чем полностью.
нуууууууу я тоже студентка... да и болею... ну в общем да, я совсем-совсем начинающий программист, я знаю об этом))
DrOffset
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
02.07.2015, 13:43 #12
Керра, вот тебе совет, который позволит избежать подобных ошибок в будущем.
Когда пишешь такие классы (с динамически выделяемыми ресурсами), первым делом, всегда, убеждайся, что они нормально копируются и присваиваются. А только потом реализуй всю остальную функциональность.
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
Croessmah
Модератор
Эксперт CЭксперт С++
13135 / 7398 / 828
Регистрация: 27.09.2012
Сообщений: 18,234
Записей в блоге: 3
Завершенные тесты: 1
03.07.2015, 06:07 #14
Цитата Сообщение от rjxk Посмотреть сообщение
ошибка сравнения. koef и right - разные типы
C++
1
float& operator[](int idx);
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.07.2015, 06:07
Привет! Вот еще темы с ответами:

Определить минимальное и максимальное расстояние между функциями - C++
Значения функций f1(x)=3x3+2x2+x+5 и f2(x)=2x3-4x2+2x-5 определены в точках x=x0(hx)xn . Определить минимальное и максимальное расстояние...

В чем разница между функциями strcat() и strcpy()? - C++
В чем разница между функциями strcat() и strcpy()?

Почему изменяется значение переменной между функциями класса? - C++
Почему-то изменяется значение переменной m(кол-во специальностей) в output_spec. Пробовал в других средах покомпилить, но m все равно...

В чем разница между функциями, прототипы которых имеют вид? - C++
int *fp(int,float); int fp(int *,float);


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
03.07.2015, 06:07
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru