如何修复Heap Corruption Detected及CRT堆缓冲区越界写入错误
解决Heap Corruption与析构函数崩溃问题
我来帮你排查并解决这个内存错误问题,你的代码里有几个关键错误直接导致了堆损坏和析构时的崩溃,咱们一步步拆解修复:
1. 析构函数的delete误用(核心崩溃原因)
你的析构函数里用delete coeff和delete exp释放内存,但这两个数组是通过new int[totalTerms]分配的数组类型内存,必须用delete[]来释放,否则会触发未定义行为(比如内存泄漏、堆结构损坏)。
修正后的析构函数:
Polynomial::~Polynomial() { if (coeff != NULL) delete[] coeff; if (exp != NULL) delete[] exp; }
同时别忘了在赋值运算符重载里,释放内存也要同步改成delete[]。
2. Add函数中错误使用sizeof获取数组长度
你在Add函数的循环里用sizeof(lhs.exp)判断终止条件,但exp是int*类型的指针,sizeof返回的是指针本身的大小(32位系统4字节,64位8字节),根本不是数组的元素个数。这会导致循环次数完全错误,要么提前终止,要么越界访问内存,直接触发堆损坏。
正确的做法是用类的totalTerms成员变量判断:
// 替换所有sizeof(lhs.exp)/sizeof(RHS.exp)的判断 while (i < this->totalTerms && j < RHS.totalTerms) { // ... 原有逻辑 }
3. Add函数中结果多项式总项数的计算逻辑错误
你原来通过k自增的方式统计总项数,逻辑有漏洞,会导致resultantPolynomial.totalTerms值不正确,后续分配数组后必然出现越界写内存的问题。正确的做法是先完整遍历两个多项式,统计合并后的准确项数:
修正后的Add函数项数统计与合并逻辑:
Polynomial Polynomial::Add(const Polynomial& RHS) { int i = 0, j = 0; int count = 0; // 第一步:统计合并后的总项数 while (i < this->totalTerms && j < RHS.totalTerms) { if (this->exp[i] > RHS.exp[j]) { count++; i++; } else if (this->exp[i] == RHS.exp[j]) { count++; i++; j++; } else { count++; j++; } } // 处理剩余未遍历完的项 while (i < this->totalTerms) { count++; i++; } while (j < RHS.totalTerms) { count++; j++; } // 初始化结果多项式 Polynomial resultantPolynomial; resultantPolynomial.totalTerms = count; resultantPolynomial.coeff = new int[count]; resultantPolynomial.exp = new int[count]; // 初始化数组元素 for (int m = 0; m < count; m++) { resultantPolynomial.coeff[m] = 0; resultantPolynomial.exp[m] = 0; } // 第二步:合并两个多项式的项 i = 0, j = 0; int k = 0; while (i < this->totalTerms && j < RHS.totalTerms) { if (this->exp[i] > RHS.exp[j]) { resultantPolynomial.exp[k] = this->exp[i]; resultantPolynomial.coeff[k] = this->coeff[i]; i++; k++; } else if (this->exp[i] == RHS.exp[j]) { resultantPolynomial.exp[k] = this->exp[i]; resultantPolynomial.coeff[k] = this->coeff[i] + RHS.coeff[j]; i++; j++; k++; } else { resultantPolynomial.exp[k] = RHS.exp[j]; resultantPolynomial.coeff[k] = RHS.coeff[j]; j++; k++; } } // 处理剩余项 while (i < this->totalTerms) { resultantPolynomial.exp[k] = this->exp[i]; resultantPolynomial.coeff[k] = this->coeff[i]; i++; k++; } while (j < RHS.totalTerms) { resultantPolynomial.exp[k] = RHS.exp[j]; resultantPolynomial.coeff[k] = RHS.coeff[j]; j++; k++; } return resultantPolynomial; }
4. 额外优化:移除不必要的对象拷贝
Add函数里Polynomial lhs = *this是多余的拷贝操作,直接用this->访问当前对象的成员即可,减少不必要的内存开销。
修正后的完整代码
整合所有修复点后的完整代码:
#include <iostream> using namespace std; 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] = 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; int count = 0; // 统计合并后的总项数 while (i < this->totalTerms && j < RHS.totalTerms) { if (this->exp[i] > RHS.exp[j]) { count++; i++; } else if (this->exp[i] == RHS.exp[j]) { count++; i++; j++; } else { count++; j++; } } // 处理剩余项 while (i < this->totalTerms) { count++; i++; } while (j < RHS.totalTerms) { count++; j++; } Polynomial resultantPolynomial; resultantPolynomial.totalTerms = count; resultantPolynomial.coeff = new int[count]; resultantPolynomial.exp = new int[count]; // 初始化数组 for (int m = 0; m < count; m++) { resultantPolynomial.coeff[m] = 0; resultantPolynomial.exp[m] = 0; } // 合并项 i = 0, j = 0; int k = 0; while (i < this->totalTerms && j < RHS.totalTerms) { if (this->exp[i] > RHS.exp[j]) { resultantPolynomial.exp[k] = this->exp[i]; resultantPolynomial.coeff[k] = this->coeff[i]; i++; k++; } else if (this->exp[i] == RHS.exp[j]) { resultantPolynomial.exp[k] = this->exp[i]; resultantPolynomial.coeff[k] = this->coeff[i] + RHS.coeff[j]; i++; j++; k++; } else { resultantPolynomial.exp[k] = RHS.exp[j]; resultantPolynomial.coeff[k] = RHS.coeff[j]; j++; k++; } } // 处理剩余项 while (i < this->totalTerms) { resultantPolynomial.exp[k] = this->exp[i]; resultantPolynomial.coeff[k] = this->coeff[i]; i++; k++; } while (j < RHS.totalTerms) { resultantPolynomial.exp[k] = RHS.exp[j]; resultantPolynomial.coeff[k] = RHS.coeff[j]; j++; k++; } return resultantPolynomial; } const Polynomial& Polynomial::operator=(const Polynomial& RHS) { if (&RHS != this) //Avoid self-assignment { 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(); }
现在运行代码,既能正确输出所有结果,也不会在析构时崩溃,堆损坏的问题也彻底解决了。
内容的提问来源于stack exchange,提问作者Akhwand Abdul Kareem
相关产品推荐
相关产品推荐

