如何修复检测到堆损坏:正常阻止后

How to fix Heap Corruption Detected: after Normal block

本文关键字:常阻止 损坏 何修复 检测      更新时间:2023-10-16

"CRT 检测到应用程序写入堆缓冲区的内存结束"错误。到达时崩溃

当它调用析构函数时我遇到了问题。 如果我注释掉析构函数,它可以正常工作。

class Polynomial
{
private:
int totalTerms;//Total terms in a Polynomial
int* coeff;//to save array of coefficients
int* exp; //to save array of exponents
public:
Polynomial()
{
this->totalTerms = 0;
this->coeff = NULL;
this->exp = NULL;
}
Polynomial(int totalTerms, int* coeff, int* exp)
{
this->totalTerms = totalTerms;
this->coeff = new int[totalTerms];
this->exp = new int[totalTerms];
for (int i = 0; i < totalTerms; i++)
{
this->coeff[i] = 0;
this->exp[i] = 0;
}
for (int i = 0; i < totalTerms; i++)
{
this->coeff[i] = coeff[i];
this->exp[i] = exp[i];
}
}
Polynomial(const Polynomial&);
~Polynomial();
void Print();
Polynomial Add(const Polynomial&);
const Polynomial& operator=(const Polynomial&);

};
Polynomial::Polynomial(const Polynomial& RHS) 
{
this->totalTerms = RHS.totalTerms;
this->coeff = new int[totalTerms];
this->exp = new int[totalTerms];
for (int i = 0; i < totalTerms; i++)
{
this->coeff[i] = RHS.coeff[i];
this->exp[i] = RHS.exp[i];
}
}
Polynomial::~Polynomial()
{
if (coeff != NULL)
delete coeff;
if (exp != NULL)
delete exp;
}
void Polynomial::Print()//Prints P1 = x^4+2x^2+5
{
for (int i = 0; i < totalTerms; i++)
{
if (coeff[i] != 0) {
cout << coeff[i];
if (exp[i] != 0)
cout << "x^" << exp[i];
if (i != totalTerms - 1)
cout << " + ";
}
}
cout << endl;
}
Polynomial Polynomial::Add(const Polynomial& RHS)
{
int i = 0, j = 0, k = 0;
Polynomial resultantPolynomial;
Polynomial lhs = *this;
while (i < sizeof(lhs.exp) && j < sizeof(RHS.exp)) {
if (lhs.exp[i] > RHS.exp[j]) {
k++; i++;
}
else if (lhs.exp[i] == RHS.exp[j])
{
k++;
i++;
j++;
}
else {
j++;
k++;
}
}
resultantPolynomial.totalTerms = k - 1;
resultantPolynomial.coeff = new int[resultantPolynomial.totalTerms];
resultantPolynomial.exp = new int[resultantPolynomial.totalTerms];
for (int i = 0; i < resultantPolynomial.totalTerms; i++)
{
resultantPolynomial.coeff[i] = 0;
resultantPolynomial.exp[i] = 0;
}
i = 0; j = 0; k = 0;
while (i < sizeof(lhs.exp) && j < sizeof(RHS.exp)) {
if (lhs.exp[i] > RHS.exp[j]) {
resultantPolynomial.exp[k] = lhs.exp[i];
resultantPolynomial.coeff[k] = resultantPolynomial.coeff[k] + lhs.coeff[i];
i++;
k++;
}
else if (lhs.exp[i] == RHS.exp[j])
{
resultantPolynomial.exp[k] = RHS.exp[j];
resultantPolynomial.coeff[k] = lhs.coeff[i] + RHS.coeff[j];
j++;
i++;
k++;
}
else {
resultantPolynomial.exp[k] = RHS.exp[j];
resultantPolynomial.coeff[k] = resultantPolynomial.coeff[k] + RHS.coeff[j];
j++;
k++;
}
}
//for (int i = 0; i < resultantPolynomial.totalTerms; i++)
//{
//  if (i < resultantPolynomial.totalTerms) {
//      resultantPolynomial.coeff[i] = resultantPolynomial.coeff[i];
//      resultantPolynomial.exp[i] = resultantPolynomial.exp[i];
//  }
//}
return (resultantPolynomial);
}
const Polynomial& Polynomial::operator=(const Polynomial& RHS)
{
if (&RHS != this)   //Avoid self-assignment
{
//De-allocate previous memory and allocate new memory IF REQUIRED
this->totalTerms = 0;
if (this->coeff != NULL)
delete this->coeff;
if (this->exp != NULL)
delete this->exp;
this->totalTerms = RHS.totalTerms;
this->coeff = new int[totalTerms];
this->exp = new int[totalTerms];
for (int i = 0; i < totalTerms; i++)
{
this->coeff[i] = RHS.coeff[i];
this->exp[i] = RHS.exp[i];
}
}
return *this;

}
int main()
{
int coeff_P1[] = { 1,2,5 }; //Coefficients for Polynomial P1
int exp_P1[] = { 4,2,0 };   //Exponents for Polynomial P1
int coeff_P2[] = { 4,3 };   //Coefficients for Polynomial P2
int exp_P2[] = { 6,2 }; //Exponents for Polynomial P2
Polynomial P1(3, coeff_P1, exp_P1);//Creates P1 with 3 terms (P1 = 1x^4 + 2x^2 + 5x^0 )
Polynomial P2(2, coeff_P2, exp_P2);//Creates P2 with 2 terms (P2 = 4x^6 + 3x^2)
cout << "P1 = "; P1.Print(); //Prints P1 = x^4+2x^2+5
cout << "P2 = "; P2.Print(); //Prints P2 = 4x^6+3x^2
Polynomial P3 = P1.Add(P2); //Adds P1 and P2 and saves result in P3. 
cout << "P3 = "; P3.Print();    //Prints P3 = 4x^6+x^4+5x^2+5   
P3 = P1;
cout << "P3 = "; P3.Print();
}

这是我注释掉析构函数时得到的输出

P1 = x^4+2x^2+5

P2 = 4x^6+3x^2

P3 = 4x^6+x^4+5x^2+5

P3 = x^4+2x^2+5

但是当我使用析构函数或函数时,屏幕上的输出是

P1 = x^4+2x^2+5

P2 = 4x^6+3x^2

我认为这里的主要问题是您使用new[]然后将其与delete匹配。

应始终将new[]delete[]匹配(非数组newdelete匹配(。

不匹配的分配和取消分配会导致未定义的行为

最好的解决方案是停止使用指针和动态分配,改用std::vector

替换

int* coeff;
int* exp;

std::vector<int> coeff;
std::vector<int> exp;

然后totalTerms是多余的 - 您可以在其中一个向量上使用size方法。

然后删除所有显式内存调用、构造函数和赋值运算符,因为编译器将为您生成的调用就足够了。使用.at而不是[进行元素访问,这样如果您尝试越界访问,至少会得到运行时异常而不是未定义的行为。然后,您的代码将正常工作。

很少需要用显式动态分配的数组对数组进行建模;它是对错误的磁铁,比如你拥有的错误。您的错误中至少有一个是由于不适当的sizeof,另一个是您使用delete而不是delete[]