Выдаёт ошибку "terminate called after throwing an instance of 'std::bad_array_new_length' what(): std::bad_array_new_length" Как её можно исправить

#include <iostream>
using namespace std;

class Array{
    int *data;
    int value;
public:
    Array(int value){
        this->value = value;
        this->data = new int[value];
    }
    Array(int value, int* data){
        this->value=value;
        this->data = new int[value];
        for (int i=0;i<this->value;i++){
        this->data[i]=data[i];
        }
    }
    Array(const Array &temp){
        this->value=temp.value;
        this->data= new int[this->value];
        for (int i=0;i<this->value;i++){
            this->data[i]=temp.data[i];
        }
    }
    Array operator()(int x, int y){
        int l = x-y-1;
        int* data2 = new int[l];
        int n=0;
        for (int i=x+1;i<y;i++){
            data2[n]=data[i];
        }
        Array arr2(l, data2);
        delete [] data2;
        return arr2;
    }

    friend istream &operator>>(istream &, Array &);
    friend ostream &operator<<(ostream &, Array &);
    ~Array(){
        delete [] data;
    }
};

istream &operator>>(istream &in, Array &arr) {
  for (int i=0;i<(arr.value);i++){
    in>>arr.data[i];
  }
  return in;
}

ostream &operator<<(ostream &out, Array &arr){
  out<<arr.value<<endl;
  for (int i=0;i<arr.value;i++){
      out<<arr.data[i]<<" ";
  }
  return out;
}

int main(){
  int n,x,y;
  cin>>n;
  Array arr(n);
  cin>>arr;
  cin>>x>>y;
  Array arr2 = arr(x,y);
  cout<<arr2;
  return 0;
}

Входные данные: размер массива, массив, два числа x и y Требуется вывести интервал исходного массива с индексами элементов между x и y


Ответы (1 шт):

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

Ну без входных данных не скажешь, но скорее всего интуитивно в operator() передаются границы диапазона сначала начало, потом конец. А далее в функции от начала отнимается конец и получается отрицательное число, которое используется при выделении памяти.

Array operator()(int x, int y)
{
   int l = x-y-1; // от начала отнимается конец l - отрицательное
   int* data2 = new int[l]; // попытка выделить массив отрицательного размера
}

Но поскольку в программе эти числа вводятся с клавиатуры, нужно в любом случае перед выделением памяти делать проверку на x<y, x и y принадлежат диапазону [0, value) и т.д. Вообще лучше было бы не operator() делать, а какую-нибудь функцию slice(). Или вообще конструктор Array(const Array& arr, int begin, int end)
Далее в цикле все элементы среза присваиваются нулевому элементу нового массива

int n=0;
for (int i=x+1; i<y; i++)
{
   data2[n]=data[i]; // n не увеличивается, все элементы присваиваются `data2[0]`
}

Ну и далее происходит утечка памяти. Поскольку не определен оператор присваивания, происходит вызов оператора присваивания по умолчанию, сгенерированного компилятором, и arr2.data присваивается указатель на буфер arr.data, а сам буфер не выделяется и не копируются данные. И далее объект arr уничтожается, буфер освобождается. И при попытке вывести массив в консоль, происходит чтение из невыделенной памяти.

Array arr2 = arr(x,y);
cout<<arr2;
→ Ссылка