【问题标题】:Heap corruption on return statement in MainMain 中的 return 语句上的堆损坏
【发布时间】:2019-04-04 22:30:22
【问题描述】:

我正在创建一个包含多项式的动态数组类。我现在遇到的问题是当我运行我的代码时,一旦它在 main 中命中 return 语句,它就会开始调用析构函数并开始从每个以 C 开头的实例中释放内存。它可以很好地删除 C,但是当它得到到 B 我得到一个堆损坏错误。我试过浏览代码,但我看不到损坏发生在哪里。谁能帮我?它给我的确切错误是“CRT 检测到应用程序在堆缓冲区结束后写入内存。”

*编辑:我很高兴得到人们的建议来帮助我的代码变得更好,但请记住,这是针对班级的,并且有特定的规则。我不能使用 STL 中的任何东西。我喜欢你能给我的任何批评。
///////////////////////标题/////////////////// ///////

class Poly

{

friend std::ostream& operator<<(std::ostream& output, const Poly& pNomial);

public:
    Poly();
    Poly(const int& coeff, const int& degree = 0);
    Poly(const Poly& copy);
    ~Poly();


    void setCoeff(const int& coeff, const int& degree);     
    bool isEmpty()const;

    Poly& operator=(const Poly& pNomial);

private:
    int* coeffs;
    int highestDegree;


};

/////////////////////////////////////////////////////////////// /////

#include "poly.h"

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

}

Poly::Poly(const int & coeff, const int & 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 Poly& 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 int& coeff, const int& 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 && check; i++)
    {
        if (coeffs[i] != 0)
        {
            check = false;
        }
    }

    return check;
}

Poly & Poly::operator=(const Poly& pNomial)
{
    if (this != &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::ostream& operator<<(std::ostream& output, const Poly& poly)
{
    if (!poly.isEmpty())
    {
        for (int i = poly.highestDegree; i >= 0; i--)
        {
            if (i == 1 && poly.coeffs[i] != 0)
            {
                if (poly.coeffs[i] >= 1)
                {
                    output << " +" << poly.coeffs[i] << "x";
                }
                else
                {
                    output << " " << poly.coeffs[i] << "x";
                }
            }
            else if (i == 0 && 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;

}``

////////////////////////////主要/////////// ////////////

#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;
}

【问题讨论】:

  • 在您考虑解决它之前,请深入内心并问自己一个问题。 Why didn't I use a vector?
  • 我项目的重点是创建我自己的动态数组类,而不是使用 STL。
  • ` for (int i = poly.highestDegree; i >= 0; i--) { if (i == 1 && poly.coeffs[i] != 0)` 到底有多大又是你的数组?
  • 你违反了单一责任原则。 Poly 负责对coeff 以及其他一些事情进行适当的生命周期管理。没有什么好事可以从中产生。如果您想出于教育目的重新发明轮子,请创建一个抽象管理动态存储持续时间对象(又名std::unique_ptr)的生命周期的类。然后创建一个抽象矢量的类(它将使用 prev 类)(又名std::vector)。然后最后创建你的Poly 类(它将使用向量类)。
  • @Vuwox 似乎使用较新的编译器在数组 new 之后添加 () 将初始化数据。

标签: c++ heap-corruption


【解决方案1】:

我必须说,我同意 cmets,并且您应该认真研究在 Poly 类中使用的资源的适当生命周期管理。 要回答您现在面临的问题,请查看setCoeff() 函数。

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

应该改为,

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

使用您当前的实现,您使用highestDegree 分配数组,并在您的for 循环中访问temp.coeffs[highestDegree],这是越界访问,即您循环到i &lt; temp.highestDegree + 1

【讨论】:

  • 您能详细解释一下正确的资源生命周期管理吗?
  • 谢谢,我不敢相信我忽略了这一点。您是否碰巧有一个链接可以清楚地解释正确的资源生命周期管理?直到今天我才听说过这个,我一直在寻求了解更多信息。
  • 我知道您不能使用 STL,但您仍然可以将 shared_ptr 用于数组,例如 std::shared_ptr&lt;int[]&gt; coeffs,这将大大减少手动删除内容的开销,因为 coeffs 的生命周期现在是绑定到shared_ptr 对象,该对象将在 shared_ptr 销毁时销毁底层资源。在 C++ 术语中,这称为RAII。此外,您还应该考虑清理您的代码,它当前包含未使用的参数等。
  • 谢谢,这真的很有帮助。
  • 只是补充一点信息,您也可以使用unique_ptr,但是您需要在复制构造函数中对自己进行深度复制,因为unique_ptrs 本身不可复制。希望这会有所帮助。
猜你喜欢
  • 2010-10-02
  • 1970-01-01
  • 2020-01-14
  • 2022-09-23
  • 2013-05-11
  • 2020-02-14
  • 1970-01-01
  • 2013-09-29
  • 2013-05-02
相关资源
最近更新 更多