Вычисление полинома в точке

Пишу программу вычисления многочлена в точке. Использую Схему Горнера. Как обычно выделяю память. При выделении памяти помимо конструктора выписываю деструктор и оператор присвоения, а также использую ссылки во избежание создания копии объекта. Вроде бы все законно. Но в конце программа выводит 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 шт):

Автор решения: DmitryK

Для объекта 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-присваивание.

→ Ссылка