C++十进制转二进制求和乘积代码sum/product函数运行异常求助
调试十进制转二进制及求和乘积代码的问题分析与修复
核心问题分析
- log2浮点数精度误差:当输入是2的幂(如512=2^9)时,
log2(512)可能因浮点数精度问题返回8.9999999999,转换为int后变成8,加1得到9,但实际512的二进制需要10位,导致binary数组长度不足,后续操作越界。 - binary数组未初始化:binary函数仅填充了余数部分,未处理的数组元素是随机值,会干扰后续计算。
- sum函数越界修改原数组:sum中直接对
a[i]、b[i]赋值(当i>=原数组长度时),属于越界访问,触发未定义行为(如崩溃、数据错乱)。 - 变长数组(VLA)非标准:sum中的
int p[z + 1] = {};是C风格变长数组,C++标准不支持,部分编译器可能报错或出现异常。 - product函数指针赋值错误:
sop = {};、q = {};这种赋值方式会使动态分配的指针丢失指向,造成内存泄漏,同时访问空指针会直接崩溃。 - product数组未初始化:每次循环创建的q数组未将未使用的位置置0,导致求和时引入随机值。
修复后的完整代码
#include <iostream> #include <cmath> using namespace std; int* binary(int num, int bits); int* sum(int a[], int lenA, int b[], int lenB); int* product(int a[], int lenA, int b[], int lenB); void display(int arr[], int len); int getBitLength(int num); // 新增:计算二进制位数,避免浮点数误差 int main() { int x, y; cout << "Enter two decimal numbers:\n"; cin >> x >> y; int t = getBitLength(x); int* a = binary(x, t); cout << "Binary: "; display(a, t); int u = getBitLength(y); int* b = binary(y, u); cout << "\nBinary: "; display(b, u); int* c = sum(a, t, b, u); int sumLen = max(t, u) + 1; cout << "\nSum: "; display(c, sumLen); int* d = product(a, t, b, u); int productLen = t + u; cout << "\nProduct: "; display(d, productLen); // 释放动态分配的内存,避免泄漏 delete[] a; delete[] b; delete[] c; delete[] d; return 0; } // 计算二进制位数,确保准确 int getBitLength(int num) { if (num == 0) return 1; int len = 0; while (num > 0) { len++; num /= 2; } return len; } int* binary(int num, int bits) { int* arr = new int[bits](); // 初始化所有元素为0 int i = 0; int n = num; while (n > 0 && i < bits) { arr[i++] = n % 2; n /= 2; } return arr; } void display(int arr[], int len) { // 找到第一个非零的最高位,避免输出前置0 int start = len - 1; while (start >= 0 && arr[start] == 0) { start--; } // 如果全是0,输出一个0 if (start < 0) { cout << 0; return; } for (int i = start; i >= 0; i--) { cout << arr[i]; } } int* sum(int a[], int lenA, int b[], int lenB) { int maxLen = max(lenA, lenB); int sumLen = maxLen + 1; int* result = new int[sumLen](); // 初始化结果数组为0 int carry = 0; for (int i = 0; i < maxLen; i++) { int bitA = (i < lenA) ? a[i] : 0; int bitB = (i < lenB) ? b[i] : 0; int total = bitA + bitB + carry; result[i] = total % 2; carry = total / 2; } // 处理最后的进位 if (carry != 0) { result[maxLen] = carry; } return result; } int* product(int a[], int lenA, int b[], int lenB) { int productLen = lenA + lenB; int* result = new int[productLen](); // 初始化结果为0 for (int i = 0; i < lenA; i++) { if (a[i] == 0) continue; // 跳过0位,优化计算 int* temp = new int[productLen](); // 临时存储当前位的乘积 for (int j = 0; j < lenB; j++) { temp[i + j] = a[i] * b[j]; } // 把临时乘积加到结果里 int* tempSum = sum(result, productLen, temp, productLen); delete[] result; delete[] temp; result = tempSum; } return result; }
关键修复说明
- 替换log2为整数位数计算:新增
getBitLength函数,用循环计算二进制位数,彻底避免浮点数精度问题。 - 初始化数组为0:所有动态分配的数组都用
new int[N]()初始化,确保未使用的位置都是0。 - sum函数避免修改原数组:通过临时变量获取a、b的对应位,不再越界修改原数组。
- 修复product的指针错误:取消错误的指针赋值,改用动态数组初始化,同时每次循环清理临时内存,避免泄漏。
- 优化display函数:正确跳过前置0,同时处理全0的情况。
- 添加内存释放:main函数中释放所有动态分配的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者محمد محمدنژاد
相关产品推荐
相关产品推荐

