C语言数字去重程序注释main变量后输出随机数问题求助
问题分析
- 核心触发问题:数组越界
你在main函数中定义int numbers[MAXNUMS - 1];,MAXNUMS宏定义为5,所以数组实际长度只有4,但后续输入循环要写入5个元素,当写入下标为4的元素时,已经超出了数组的合法访问范围,属于典型的栈越界。
栈上的变量是连续排布的,你原本在numbers数组后定义了int unique_list = 0;,刚好占用了numbers[4]对应的内存位置,所以越界写入的内容会覆盖这个变量的值。但这个变量在main里从来没有被使用过,所以看起来程序能正常运行。当你把这行注释后,越界写入的内容会覆盖栈上的其他关键数据(比如栈帧基址、函数返回地址等),直接导致程序运行异常,出现随机输出甚至崩溃。 - 隐藏问题:去重逻辑错误
RemoveDuplicates函数中内层循环的break位置错误,没有放到if判断的大括号内,导致内层循环永远只会判断j=0的第一个元素,无法匹配后续位置的重复值,去重功能本身就不生效,比如输入序列7、2、2、3、4,你当前的代码会输出7、2、2、3、0,无法去除第二个2。 - 规范问题:传参写法不规范
调用RemoveDuplicates时你写的是&numbers,数组名本身就代表首元素地址,直接传numbers即可,两者地址值一致但类型有区别,属于不规范写法。
修复后的完整代码
#include <stdio.h> #define MAXNUMS 5 void RemoveDuplicates(int list[]); int main() { int idx, numbers[MAXNUMS]; // 修复数组长度 printf("Enter %d numbers.\n", MAXNUMS); for(idx = 0; idx < MAXNUMS; idx++) { printf("input number %d: ", idx + 1); scanf("%d", &numbers[idx]); } printf("pass"); RemoveDuplicates(numbers); // 修复传参写法 printf("\npass 1"); printf("\nThe new list is:\n"); for (idx = 0; idx < MAXNUMS; idx++) printf("%d\n", numbers[idx]); return 0; } void RemoveDuplicates(int list[]) { int i; int j; int found; int unique_list = 0; for (i = 0; i < MAXNUMS; i++) { found = 0; for (j = 0; j < unique_list; j++) { if (list[j] == list[i]) { found = 1; break; // 修复break位置,放到if判断内部 } } if (!found) { list[unique_list] = list[i]; unique_list++; } } for (j = unique_list; j < MAXNUMS; j++) list[j] = 0; return; }
内容的提问来源于stack exchange,提问作者Osslot
相关产品推荐
相关产品推荐

