Повреждение кучи при выполнении инструкции return в Main

#c #heap-corruption

#c #повреждение кучи

Вопрос:

Я создаю класс динамического массива, который содержит многочлены. Проблема, с которой я сталкиваюсь прямо сейчас, заключается в том, что когда я запускаю свой код, как только он попадает в инструкцию return в main, он начинает вызывать деструктор и начинает освобождать память от каждого экземпляра, начинающегося с C. Он удаляет C нормально, но когда он доходит до B, я получаю ошибку повреждения кучи. Я попытался просмотреть код, но я не могу увидеть, где происходит повреждение. Кто-нибудь может мне помочь? Точная ошибка, которую это выдает, заключается в том, что «CRT обнаружил, что приложение записало в память после завершения буфера кучи».

* Редактировать: Я более чем рад получить рекомендации пользователей, которые помогут улучшить мой код, но помните, что это для класса и имеет определенные правила. Я не могу использовать что-либо из STL. Мне нравится любая критика, которую вы можете мне высказать.
/////////////////////////// Заголовок/////////////////////////////

 class Poly

{

friend std::ostreamamp; operator<<(std::ostreamamp; output, const Polyamp; pNomial);

public:
    Poly();
    Poly(const intamp; coeff, const intamp; degree = 0);
    Poly(const Polyamp; copy);
    ~Poly();


    void setCoeff(const intamp; coeff, const intamp; degree);     
    bool isEmpty()const;

    Polyamp; operator=(const Polyamp; pNomial);

private:
    int* coeffs;
    int highestDegree;


};
  

///////////////////////////CPP////////////////////////

 #include "poly.h"

Poly::Poly()
{
   highestDegree = 0;
   coeffs = new int[highestDegree 1]();

}

Poly::Poly(const int amp; coeff, const int amp; degree)
{
   if (degree >= 0)
   {
      highestDegree = degree;
      coeffs = new int[highestDegree   1]();
      coeffs[degree] = coeff;
   }
   else
   {
      highestDegree = 0;
      coeffs = new int[highestDegree   1]();

   }


}

Poly::Poly(const Polyamp; copy)
{
    highestDegree = copy.highestDegree;
    coeffs = new int[highestDegree   1]();

    for (int i = 0; i < copy.highestDegree   1; i  )
    {
        coeffs[i] = copy.coeffs[i];
    }
}

Poly::~Poly()
{
    delete[] coeffs;
}

void Poly::setCoeff(const intamp; coeff, const intamp; degree)
{
    if (degree > this->highestDegree)
    {
        Poly temp = *this;
        delete[] this->coeffs;
        this->highestDegree = degree;
        this->coeffs = new int[highestDegree]();



        for (int i = 0; i < temp.highestDegree   1; i  )
        {
            this->coeffs[i] = temp.coeffs[i];
        }       

    }

    if (degree >= 0)
    {
        this->coeffs[degree] = coeff;
    }

}

bool Poly::isEmpty()const
{
    bool check = true;

    for (int i = 0; i < highestDegree   1 amp;amp; check; i  )
    {
        if (coeffs[i] != 0)
        {
            check = false;
        }
    }

    return check;
}

Poly amp; Poly::operator=(const Polyamp; pNomial)
{
    if (this != amp;pNomial)
    {
        delete[] this->coeffs;
        this->highestDegree = pNomial.highestDegree;
        this->coeffs = new int[this->highestDegree   1]();

        for (int i = 0; i < pNomial.highestDegree   1; i  )
        {
            this->coeffs[i] = pNomial.coeffs[i];
        }
    }

    return *this;
}

std::ostreamamp; operator<<(std::ostreamamp; output, const Polyamp; poly)
{
    if (!poly.isEmpty())
    {
        for (int i = poly.highestDegree; i >= 0; i--)
        {
            if (i == 1 amp;amp; poly.coeffs[i] != 0)
            {
                if (poly.coeffs[i] >= 1)
                {
                    output << "  " << poly.coeffs[i] << "x";
                }
                else
                {
                    output << " " << poly.coeffs[i] << "x";
                }
            }
            else if (i == 0 amp;amp; poly.coeffs[i] != 0)
            {
                if (poly.coeffs[i] >= 1)
                {
                    output << "  " << poly.coeffs[i];
                }
                else
                {
                    output << " " << poly.coeffs[i];
                }
            }
            else if (poly.coeffs[i] != 0)
            {
                if (poly.coeffs[i] >= 1)
                {
                    output << "  " << poly.coeffs[i] << "x^" << i;
                }
                else
                {
                    output << " " << poly.coeffs[i] << "x^" << i;
                }

            }
        }
    }
    else
    {
        output << " 0";
    }



    return output;

}``
  

/////////////////////////////////Main/////////////////////////

 #include "poly.h"
#include <iostream>

int main()
{
    Poly A, B(5, 7), C(2);
    B.setCoeff(2, 10);
    B.setCoeff(1, 3);
    B.setCoeff(5, 4);


    std::cout << A << std::endl;
    std::cout << B << std::endl;
    std::cout << C << std::endl;





    return 0;
}
  

Комментарии:

1. Прежде чем вы даже подумаете о ее решении, загляните глубоко внутрь и задайте себе один вопрос. Why didn't I use a vector?

2. Смысл моего проекта в том, чтобы создать свой собственный класс dynamic array и не использовать STL.

3. ` for (int i = poly.highestDegree; i >= 0; i—) { if (i == 1 amp;amp; poly.coeffs[i] != 0)` Насколько велик ваш массив еще раз?

4. Вы нарушаете принцип единой ответственности. Poly отвечает за надлежащее управление временем жизни coeff , а также за множество других вещей. Ничего хорошего из этого не выйдет. Если вы хотите изобрести велосипед для образовательных целей, тогда создайте класс, который абстрагирует управление временем жизни объекта dynamic storage duration (он же std::unique_ptr ). Затем создайте класс, который абстрагирует вектор (он будет использовать предыдущий класс) (он же std::vector ). Затем, наконец, создайте свой Poly класс (который будет использовать класс vector).

5. @Vuwox Кажется, что с добавлением более новых компиляторов () после array new данные будут инициализироваться.

Ответ №1:

Я должен сказать, что я согласен с комментариями, и вам следует серьезно заняться надлежащим управлением временем жизни ресурсов, которые вы используете в Poly классе. Чтобы ответить на проблему, с которой вы столкнулись, взгляните на setCoeff() функцию.

 this->coeffs = new int[highestDegree]();
  

должно быть изменено на,

 this->coeffs = new int[highestDegree   1]();
  

В вашей текущей реализации вы выделяете массив с помощью highestDegree и в вашем for цикле вы получаете доступ temp.coeffs[highestDegree] к тому, что находится за пределами доступа, т. е. вы выполняете цикл до i < temp.highestDegree 1 .

Комментарии:

1. Можете ли вы подробнее рассказать о правильном управлении ресурсами в течение всего срока службы?

2. Спасибо, я не могу поверить, что я это упустил. У вас случайно нет ссылки, которая четко объясняет правильное управление ресурсами в течение всего срока службы? Я никогда не слышал об этом до сегодняшнего дня, и я всегда стремлюсь узнать больше.

3. Я понимаю, что вы не можете использовать STL, но вы все равно можете использовать shared_ptr для массива, т. Е. что-то вроде std::shared_ptr<int[]> coeffs , что значительно уменьшит накладные расходы на удаление объектов вручную, поскольку время жизни coeffs теперь привязано к shared_ptr объекту, который уничтожит базовые ресурсы при уничтожении shared_ptr. В терминах C это называется RAII . Кроме того, вам следует подумать о том, чтобы выполнить очистку вашего кода, поскольку в настоящее время он содержит неиспользуемые параметры и т.д.

4. Спасибо, это было действительно очень полезно.

5. Вы также можете использовать unique_ptr просто для добавления некоторой информации, но вам нужно выполнить глубокое копирование самостоятельно в конструкторе копирования, поскольку unique_ptr сами по себе они не копируются. Надеюсь, это поможет.