C语言动态数组重复元素删除问题求助
解决动态数组去重失败的问题
我来帮你排查下代码里的问题,你的去重逻辑和文件读取部分都有几个关键点需要修正,咱们一步步来:
1. 文件读取的feof陷阱
你用while(!feof(f))作为循环条件是个常见的坑——feof只有在尝试读取并失败后才会被置为真,这意味着当文件最后一个整数读完后,循环还会多执行一次:这次fscanf会失败,但你还是会realloc数组、给v[n]赋一个不确定的垃圾值,同时n会多计数1,导致数组末尾出现无效数据,后续排序和去重都会受影响。
正确的做法是把fscanf的返回值作为循环条件,因为fscanf成功读取一个整数时会返回1,遇到文件结束或读取失败时返回其他值:
while(fscanf(f,"%d", &v[n]) == 1) { v = realloc(v, (n+1)*sizeof(int)); n++; }
(另外,malloc和realloc在C里不需要强制转换为int*,不过这不是功能问题,只是代码风格的小细节)
2. 去重逻辑的核心错误
你当前的去重代码逻辑完全不对:
- 循环从
j=n开始,v[j]是数组越界访问(数组下标范围是0到n-1),会触发未定义行为; - 每次发现重复就直接
realloc缩小数组,但没有把重复元素后面的有效数据往前移动,也没有更新n的值,最后输出还是用原来的n,会访问到已经被释放的内存或垃圾值; - 频繁调用
realloc效率极低,也不是正确的去重姿势。
因为数组已经用快速排序排好序了,我们可以用双指针法高效去重:
- 用变量
k记录不重复元素的最后位置,初始为0; - 从
i=1开始遍历数组,如果当前元素v[i]和v[k]不相等,就把v[i]放到v[++k]的位置; - 遍历结束后,
k+1就是不重复元素的总个数,再重新分配数组内存并更新n。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> // 假设你的OrdenarQuicksort函数已经正确实现 void OrdenarQuicksort(int *v, int inicio, int fim); int main(){ FILE *f; int *v; int n=0, i, k; f = fopen("InteirosComRepetidos.txt","r"); if(f == NULL) { // 别忘了检查文件是否成功打开 printf("无法打开文件!\n"); return 1; } v = malloc(sizeof(int)); if(v == NULL) { // 检查内存分配是否成功 printf("内存分配失败!\n"); fclose(f); return 1; } // 正确读取文件内容 while(fscanf(f,"%d", &v[n]) == 1) { v = realloc(v, (n+1)*sizeof(int)); if(v == NULL) { // 检查realloc是否成功 printf("内存重新分配失败!\n"); free(v); fclose(f); return 1; } n++; } fclose(f); // 读完文件及时关闭 OrdenarQuicksort(v, 0, n-1); // 注意这里的参数,fim应该是n-1而不是n,避免越界 printf("排序后:\n"); for(i=0; i<n; i++){ printf("%d\n",v[i]); } // 去重逻辑:双指针法 if(n == 0) { // 处理空数组的情况 printf("无元素可去重\n"); } else { k = 0; for(i=1; i<n; i++){ if(v[i] != v[k]){ v[++k] = v[i]; } } // 重新分配内存到不重复元素的个数 v = realloc(v, (k+1)*sizeof(int)); if(v == NULL) { printf("内存重新分配失败!\n"); free(v); return 1; } n = k+1; // 更新元素个数 } printf("去重后:\n"); for(i=0; i<n; i++){ printf("%d\n",v[i]); } free(v); // 释放动态分配的内存 system("pause"); return 0; }
额外注意点
- 每次调用
malloc和realloc都要检查返回值是否为NULL,避免内存分配失败导致的程序崩溃; - 调用
OrdenarQuicksort时,fim参数应该是n-1,因为数组下标从0开始,否则会访问越界; - 用完文件和动态内存后要及时关闭/释放,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Rúben Cardoso
相关产品推荐
相关产品推荐

