求解决2的n次幂计算程序的C6385/C6386警告及运行错误问题
问题分析与修正方案
先逐个拆解你遇到的问题:
核心错误点
- 数组索引误用:
MultiplyArrays内层循环里,你写了ar1[i] * ar2[i],这里的ar2[i]应该是ar2[j]——用i索引ar2会导致当i超过ar2的长度(比如len2=1时,i可能大于0),直接访问无效内存,这是触发C6385/C6386警告的主要原因。 - 前导零处理逻辑错误:原代码移动有效元素时,在循环中每次递减
resultLen,导致元素复制范围混乱,甚至越界。正确的做法是先统计前导零的数量,再一次性把有效元素移到数组开头,统一更新长度。 - 结果数组空间未动态扩容:主函数里的
number数组初始长度仅为1,但计算高次幂时结果长度会持续增长,原代码没有重新分配内存,导致写入超出原数组范围的内存,触发主函数的C6385警告。 - 自乘时的野指针问题:当power为偶数时,直接用
array乘array会因为MultiplyArrays先释放原array内存,导致另一个操作数变成野指针,必须先复制一份临时数组作为操作数。
修正后的完整代码
头文件
#include <iostream> #include <string> using namespace std;
修正后的MultiplyArrays函数
void MultiplyArrays(int*& ar1, int* len1, int* ar2, int len2) { int resultLen = *len1 + len2; int* result = new int[resultLen](); // 初始化全0,避免垃圾值干扰 for (int i = *len1 - 1; i >= 0; --i) { int carry = 0; for (int j = len2 - 1; j >= 0; --j) { // 修复ar2的索引错误 int tempSum = result[i + j + 1] + ar1[i] * ar2[j] + carry; result[i + j + 1] = tempSum % 10; carry = tempSum / 10; } result[i] += carry; } // 统计前导零数量 int leadingZeros = 0; while (leadingZeros < resultLen && result[leadingZeros] == 0) { leadingZeros++; } // 计算新长度,处理全零情况(比如0乘任何数) int newLen = resultLen - leadingZeros; if (newLen == 0) { newLen = 1; } // 重新分配ar1的内存,释放旧内存 delete[] ar1; ar1 = new int[newLen]; if (newLen == 1 && leadingZeros == resultLen) { ar1[0] = 0; } else { // 复制有效元素到新数组 for (int i = 0; i < newLen; ++i) { ar1[i] = result[leadingZeros + i]; } } *len1 = newLen; delete[] result; }
修正后的RaisePowerTwo函数
void RaisePowerTwo(int* len, int*& array, int power) { // 处理2^0=1的情况(可选,根据需求调整) if (power == 0) { delete[] array; array = new int[1]; array[0] = 1; *len = 1; return; } if (power == 1) { delete[] array; array = new int[1]; array[0] = 2; *len = 1; } else if (power % 2 == 1) { RaisePowerTwo(len, array, power - 1); int* timeAr = new int[1]; timeAr[0] = 2; MultiplyArrays(array, len, timeAr, 1); delete[] timeAr; } else if (power % 2 == 0) { RaisePowerTwo(len, array, power / 2); // 复制原数组作为临时操作数,避免自乘时内存失效 int* tempArray = new int[*len]; for (int i = 0; i < *len; ++i) { tempArray[i] = array[i]; } int tempLen = *len; MultiplyArrays(array, len, tempArray, tempLen); delete[] tempArray; } }
主函数
int main() { int n; cin >> n; int length = 1; int* number = new int[length](); RaisePowerTwo(&length, number, n); for (int i = 0; i < length; ++i) { cout << number[i]; } cout << endl; // 输出换行,更规范 delete[] number; return 0; }
说明
- 用
int*& ar1引用传递指针,允许函数内部重新分配数组内存,解决了原数组空间不足的问题。 - 修复索引错误后,低次幂的运行错误会消失;动态扩容后,高次幂的缓冲区溢出问题也会解决。
- 增加了
power=0的处理,让程序更严谨,你可以根据需求决定是否保留。
内容的提问来源于stack exchange,提问作者Ilya Ronzin
相关产品推荐
相关产品推荐

