Деструктор объекта ломает программу

#include <iostream> 
#include <string>

using namespace std;

class boolArr
{
private:
    size_t count = 0;
public:
    bool* arr;              //Объявление массива

    size_t get_count() { return count; }
    boolArr(size_t count)
    {
        this->count = count;    //Инициализация длинны массива
        arr = new bool[count];  //Инициализация памяти для массива
        for (size_t i = 0; i < count; i++)
            arr[i] = 0;
    }
    ~boolArr()
    {
        delete [] arr;
        arr = nullptr;
    }
    
    bool& (operator[])(const size_t ind)
    {
        return arr[ind];
    }
    friend boolArr (operator&&) (boolArr& a, boolArr& b)
    {
        if (a.count != b.count) throw exception(); // Массивы должны быть одной размерности
        boolArr c(a.count);
        for (int i = 0; i < a.count; i++)
        {
            c[i] = a[i] && b[i];
        }
        return c;

    }
    friend boolArr(operator||) (boolArr& a, boolArr& b)
    {
        // if (a.count != b.count) throw exception(); // Массивы должны быть одной размерности || Делаем исключение
        if (a.get_count() != b.get_count())
        {
            cout << "Такое невозможно!Массивы разной длинны";
            boolArr C(0);
            return C;
        }
        boolArr c(a.count);
        for (int i = 0; i < a.count; i++)
        {
            c[i] = a[i] || b[i];
        }
        return c;
    }
    boolArr operator! () 
    {
        for (size_t i = 0; i < count; i++)
        {
            this->arr[i] = !this->arr[i];
        }
        return *this;
    }
};
void print(boolArr A)
{
    for (int i = 0; i < A.get_count(); i++)
        cout << A[i] <<" ";

}
void println(boolArr A)
{
    for (int i = 0; i < A.get_count(); i++)
        cout << A[i] << " ";
    cout << "\n";
}

void main()
{
    setlocale(LC_ALL, "rus");
    size_t a, b;

    cout << "Введите длинну массива А >> ";
    cin >> a;
    boolArr A(a);
    cout << "Введите элементы массива А  поочередно>> ";
    for (int i = 0; i < a; i++)
        cin>>A[i];

    cout << "Введите длинну массива B >> ";
    cin >> b;
    boolArr B(b);
    cout << "Введите элементы массива B  поочередно>> ";
    for (int i = 0; i < b; i++)
        cin >> B[i];

    cout << "|| ";
    println(A || B);
}

Здравствуйте, столкнулся со следующей проблемой, которую даже и загуглить то не могу так, чтобы найти корректные ответы, потому обращаюсь к stack. После функции перегрузки объект в функции удаляется, однако,я думал, что перед этим он возвратится и передастся в функцию println, если я прописываю деструктор - все ломается, если нет - все работает исправно.И это взрывает мне мозг.Почему так происходит и как сделать мой код корректным?


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

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

При отсутствии конструктора копирования компилятор генерирует таковой по умолчанию, который выполняет поверхностное копирование, т.е. просто переписывает член-указатель. Деструктор освобождает память, деструктор копии освобождает память второй раз, что не разрешено, является UB и источником всяческих проблем...

Чтобы избежать проблемы, напишите правильные копирующий конструктор (да и оператор присваивания), каковые создают новый массив и копируют в него массив из копируемого объекта (глубокое копирование), а не просто копируют указатель на одно и то же место в памяти.

В вашей программе конструктор копирования вызывается, например, там, где вы передаете объект в функцию по значению, а не по ссылке.

P.S. Метка c никакого отношения к данному чисто C++'ному вопросу не имеет.

→ Ссылка