Вычисление полинома в точке
Пишу программу вычисления многочлена в точке. Использую Схему Горнера. Как обычно выделяю память. При выделении памяти помимо конструктора выписываю деструктор и оператор присвоения, а также использую ссылки во избежание создания копии объекта. Вроде бы все законно. Но в конце программа выводит free(): invalid pointer. Скорее всего опять что-то не учел. Может подскажете в чем ошибка?
#include<iostream>
using namespace std;
class Polynom{
int x, n, *data, result;
public:
Polynom(){
x = 0; n = 0;
}
Polynom(int N, int X){
n = N;
x = X;
data = new int[n];
}
~Polynom(){
delete[] data;
}
void scan(){
cout << "Input coeff:"<<endl;
for(int i = 0; i < n; i++){
cin >> data[i];
}
}
void print(){
cout << result;
}
Polynom &operator =(const Polynom &ob){
if(this == &ob) return *this;
if(data) delete[] data;
n = ob.n;
x = ob.x;
data = new int[n];
for(int i = 0; i < n; i++)
data[i] = ob.data[i];
return *this;
}
int poli(){
result = data[0];
for(int i = n-1; i > 0; i--){
result=result*x + data[i];
}
return result;
}
friend Polynom operator -=(const Polynom &ob1, const Polynom &ob2);
};
/*Polynom operator -=(const Polynom &ob1, const Polynom &ob2){
Polynom temp;
ob1.data[i] -= ob2.data[i];
return temp;
}
*/
int main(){
int n, x;
cout << "Input n and x:";
cin >> n >> x;
Polynom ob1(n,x), ob2;
ob1.scan();
ob1.poli();
}
Ответы (1 шт):
Для объекта Polynom ob2; в конструкторе не выделялась память и указатель не обнулялся, а при вызове деструктора вызывается команда delete[] data;для ненулевого указателя.
В принципе должно решить проблему, т.к. сейчас delete корректно отрабатывает с нулевыми указателями:
Polynom()
{
x = 0;
n = 0;
data = nullptr;
}
Ну или вручную проверять в деструкторе
~Polynom()
{
if(!data) delete[] data;
}
По-нормальному, нужно еще проверить, что в конструктор с параметрами передано корректное n > 0. Иначе вы можете нарваться на ту же проблему - память не выделилась, а вы попытаетесь её удалить.
Polynom(int N, int X)
{
n = N;
x = X;
data = new int[n]; // если n отрицательная?
}
То же самое с копирующим конструктором. После delete[] обнулите указатель, ведь неизвестно сможет ли new() выделить память. А вообще, чтобы состояние объекта сохранялось корректным, лучше сначала выделить память на временный указатель и если всё прошло нормально - только тогда удалять старую память.
И если вы сами написали один конструктор, значит необходимо соблюсти правило пяти Т.е. ещё нужно дописать move-конструктор и move-присваивание.