Перегруженный оператор '=' с использованием массивов выдает ошибку времени выполнения C ++ - PullRequest
0 голосов
/ 26 февраля 2020

Я пытаюсь установить перегруженный оператор '=' для пользовательского класса Array для практики, но, похоже, он вызывает ошибку во время выполнения.

class Array {
    private:
        static int numberOfElements; //class static variable
        int size;
        int* numbers;

    public:
        Array(int);
        Array(const Array&);
        ~Array();

        int getSize();
        static int getNumberOfElements();

        Array& operator =(const Array&);
};

Эта перегруженная операторная функция выдает правильный вывод, но с ошибкой времени выполнения:

Array& Array::operator =(const Array& newArray) {
    numberOfElements = numberOfElements - size + newArray.size;
    size = newArray.size;
    for (int i = 0; i < size; i++)
        numbers[i] = newArray.numbers[i];
    return *this;
}

Раньше у меня было

Array& Array::operator =(const Array& newArray) {
    delete[] numbers;
    numberOfElements = numberOfElements - size + newArray.size;
    size = newArray.size;
    numbers = new int[size];
    for (int i = 0; i < size; i++)
        numbers[i] = newArray.numbers[i];
    return *this;
}

, которое не создает среду выполнения, но создает массив, заполненный мусором. numberOfElements просто отслеживает общее количество элементов во всех массивах, и не должно быть фактором ошибки. Я уверен, что проблема заключается в выделении динамического c, но я не могу логически понять, почему он выбрасывает среду выполнения, если я перезаписываю исходный массив с помощью newArray, и почему последний заполняется мусором даже если для выделенного массива заданы элементы newArray.

1 Ответ

0 голосов
/ 26 февраля 2020

Если newArray.size больше this->size, ваша operator= очищает память. Он должен перераспределить свой массив numbers[], чтобы учесть больший размер, который вы делали изначально (только не безопасным способом).

Если newArray.size не больше this->size, перераспределение не требуется, просто скопируйте значения из newArray.numbers в this->numbers как есть, следя за тем, чтобы не превышать меньшее из newArray.size или this->size.

Попробуйте что-то более похожее на это:

Array& Array::operator=(const Array& newArray)
{
    if (&newArray != this)
    {
        if (size != newArray.size)
        {
            numberOfElements -= size;

            delete[] numbers;
            numbers = NULL;
            size = 0;

            numbers = new int[newArray.size];
            size = newArray.size;

            numberOfElements += size;
        }

        for (int i = 0; i < size; ++i)
            numbers[i] = newArray.numbers[i];
    }

    return *this;
}

Который затем можно сделать более безопасным, используя идиома копирования-обмена , используя существующий конструктор копирования:

Array::Array(int num)
{
    size = num;
    numbers = new int[num];
    numberOfElements += num;
}

Array::Array(const Array &srcArray)
{
    size = src.size;
    numbers = new int[size];
    for (int i = 0; i < size; ++i)
        numbers[i] = srcArray.numbers[i];
    numberOfElements += size;
}

Array::~Array()
{
    delete[] numbers;
    numberOfElements -= size;
}

#include <algorithm>
Array& Array::operator=(const Array& newArray)
{
    if (this != &newArray)
    {
        if (size != newArray.size)
        {
            Array tmp(newArray);
            std::swap(numbers, tmp.numbers);
            std::swap(size, tmp.size);
        }
        else
        {
            for (int i = 0; i < size; ++i)
                numbers[i] = newArray.numbers[i];
        }
    }

    return *this;
}
...