计算大整数的程序中Realloc偶发栈溢出问题排查
问题分析与修复方案
1. 内存分配体系混用(核心偶发错误原因)
代码里混合使用了C++的new[]和C语言的realloc/free,这属于未定义行为:
- 所有构造函数均使用
new char[]分配digits内存 Sub函数却用realloc重新分配该指针指向的内存
realloc仅能操作malloc/calloc/realloc分配的内存,用它处理new分配的内存会直接破坏堆结构,导致偶发栈溢出、崩溃等不可预测的错误。
修复方法:
统一使用C++内存管理方式,替换realloc为new[]+内存拷贝:
if (this->length < index) { char* tmp = new char[index + 1]; if (tmp == nullptr) { cerr << "Memory reallocation failed, the program will terminate." << endl; delete[] this->digits; exit(0); } // 拷贝原有数据 strcpy(tmp, this->digits); // 释放旧内存 delete[] this->digits; this->digits = tmp; this->length = index; this->digits[this->length] = '\0'; }
2. 递归调用触发栈溢出
Sub函数借位时递归调用自身,当连续借位深度过大(比如10000位超大整数减1),会耗尽栈空间触发栈溢出。这种错误的出现频率取决于借位深度,因此表现为偶发。
修复方法:
将递归改为循环实现,避免栈溢出:
// 替换原递归逻辑 int borrow = num - '0'; int current_idx = index - 1; while (borrow > 0 && current_idx >= 0) { int digit = this->digits[current_idx] - '0'; digit -= borrow; if (digit < 0) { digit += 10; borrow = 1; } else { borrow = 0; } this->digits[current_idx] = digit + '0'; current_idx--; } // 若借位未清0,扩展位数处理 if (borrow > 0) { char* tmp = new char[this->length + 2]; strcpy(tmp + 1, this->digits); tmp[0] = '9'; delete[] this->digits; this->digits = tmp; this->length += 1; this->digits[this->length] = '\0'; }
同时注意原代码的计算错误:this->digits[index - 1] -= num + '0';会导致数值溢出,正确写法应为this->digits[index - 1] -= (num - '0');,因为要减去的是num对应的数值而非字符ASCII值之和。
3. 构造函数的placement new风险
inf_int(int n)中,当i=0(即n=0)时使用new (this) inf_int();重新构造对象,会引发:
- 若对象已分配内存,直接造成内存泄漏
- 二次调用构造函数触发未定义行为
修复方法:
直接初始化成员变量,摒弃placement new:
if (i == 0) { this->digits = new char[2]; this->digits[0] = '0'; this->digits[1] = '\0'; this->length = 1; this->thesign = true; }
4. 字符串处理的内存越界
inf_int(const char* str)构造函数存在多处越界:
char* answer = new char[strlen(str)];未给字符串结束符'\0'留空间,strcpy(answer, str)会越界写入- 处理负号时
char* solution = new char[strlen(str)];,后续solution[strlen(str)] = '\0';的索引超出数组范围
修复方法:
修正内存分配大小:
// 修正answer的分配 char* answer = new char[strlen(str) + 1]; // 处理负号时的solution分配 size_t num_len = strlen(str) - 1; char* solution = new char[num_len + 1];
内容的提问来源于stack exchange,提问作者Dagun
相关产品推荐
相关产品推荐

