C++动态分配内存实现Kaprekar自数无输出,静态数组正常
解决Kaprekar自数动态数组无输出的问题
嘿,我看到你在实现D.R. Kaprekar自数的时候遇到了一个奇怪的问题——静态数组能正常输出结果,但换成动态分配内存的版本就没反应了。咱们来一步步拆解问题出在哪,以及怎么修复:
问题根源:数组越界访问导致未定义行为
先看你的d()函数,它的作用是计算一个数加上自身各位数字的和,这个结果必然大于原数。当你遍历i从0到9999时,最大的d(i)是多少呢?算一下:i=9999时,d(9999)=9999+9+9+9+9=10035。
但你动态分配的数组只有10000个元素,索引范围是0~9999。这时候访问arr[10035]就属于数组越界访问,这是C++里的未定义行为——它可能会破坏数组的内存结构,甚至覆盖程序里的其他变量(比如循环计数器、内存管理的元数据),导致后面的输出循环根本没法正常执行,自然就没输出了。
而你用静态数组时能正常运行,大概率是因为静态数组的大小设得足够大(比如超过10035),刚好避开了越界问题。
修复方案:分配足够大的动态数组
要解决这个问题,我们只需要先计算出d(i)的最大值,然后分配对应大小的动态数组,确保所有数组访问都在合法范围内。这里提供两种修复思路:
思路1:调整原逻辑的数组大小
基于你原来的代码逻辑,修改数组大小并修正循环:
#include<iostream> using namespace std; int d(int num) { int dn = num; while (num != 0) { dn += num % 10; num = num / 10; } return dn; } int main() { const int MAX_NUM = 9999; // 计算最大的d(n):9999的各位和是36,所以最大值是9999+36=10035 const int MAX_D_VALUE = MAX_NUM + 9*4; // 分配足够大的数组,覆盖所有可能的d(n)结果 int* arr = new int[MAX_D_VALUE + 1]; // 初始化数组:1~MAX_NUM的位置设为对应数值,其余设0 for (int i = 0; i <= MAX_D_VALUE; i++) { arr[i] = (i <= MAX_NUM) ? (i + 1) : 0; } // 标记非自数:遍历1~MAX_NUM,将对应的d(n)位置设为0 for (int n = 1; n <= MAX_NUM; n++) { int dn = d(n); if (dn <= MAX_D_VALUE) { arr[dn] = 0; } } // 输出自数:筛选出未被标记的数 for (int i = 1; i <= MAX_NUM; i++) { if (arr[i-1] > 0) { cout << i << endl; } } delete[] arr; return 0; }
思路2:用更清晰的标记数组逻辑
如果觉得原逻辑有点绕,可以改用标记数组的方式,代码可读性更高:
#include<iostream> using namespace std; int d(int num) { int dn = num; while (num != 0) { dn += num % 10; num = num / 10; } return dn; } int main() { const int MAX_NUM = 9999; const int MAX_D_VALUE = MAX_NUM + 9*4; // 动态分配标记数组,初始化为0(0表示是自数,1表示非自数) int* is_non_self = new int[MAX_D_VALUE + 1](); // 标记所有非自数 for (int n = 1; n <= MAX_NUM; n++) { int dn = d(n); if (dn <= MAX_D_VALUE) { is_non_self[dn] = 1; } } // 输出所有自数 cout << "1到9999之间的Kaprekar自数:" << endl; for (int n = 1; n <= MAX_NUM; n++) { if (is_non_self[n] == 0) { cout << n << endl; } } delete[] is_non_self; return 0; }
关键总结
- 动态数组版本无输出的核心原因是数组大小不足,导致越界访问触发未定义行为。
- 解决这类问题的关键是先明确数组需要容纳的最大元素值,再分配对应大小的内存,避免越界。
内容的提问来源于stack exchange,提问作者haeinsa
相关产品推荐
相关产品推荐

