C代码字母排序程序崩溃求助:仅能处理10个单词及优化咨询
问题分析与解决方案
你的程序处理超过10个单词就崩溃,大概率是固定大小的数组限制或者内存越界访问导致的——和Code::Blocks用的编译器(默认是GCC)关系不大,编译器本身不会限制你处理的单词数量,问题出在代码逻辑上。我来拆解可能的原因,再给你修复和优化方案:
可能的崩溃原因
- 固定大小的指针数组:如果你的代码里定义了类似
char *words[10];的固定长度数组,当读取的单词超过10个时,会直接越界写入栈内存,破坏程序的栈结构,导致崩溃。 - 排序函数的边界错误:你的
arrange函数如果写死了循环次数(比如固定循环10次),当单词数量超过10时,会访问不存在的指针,触发内存错误。 - 内存分配遗漏检查:如果用
malloc分配字符串内存,但没检查分配是否成功,当内存不足时会拿到空指针,后续操作空指针就会崩溃。
修复与优化步骤
1. 改用动态内存存储单词
不要用固定大小的数组,而是根据实际读取的单词数量动态分配内存,甚至可以边读边扩容:
- 先初始化一个有初始容量的指针数组,当单词数量达到容量时,用
realloc扩容。 - 每个单词用
strdup(或malloc+strcpy)分配独立的内存,避免字符串覆盖。
2. 修正排序函数的边界逻辑
排序循环要基于实际的单词数量n,而不是固定值。另外,用标准库的qsort比自己写排序函数更高效、更可靠。
3. 完善错误处理
对所有文件操作、内存分配的返回值做检查,避免因资源获取失败导致的崩溃,同时在出错时及时释放已分配的内存,避免内存泄漏。
优化后的完整代码示例
#include<stdio.h> #include<string.h> #include<stdlib.h> // 自定义排序函数(也可以直接用qsort) void arrange(int n, char *x[]) { for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (strcmp(x[j], x[j+1]) > 0) { char *temp = x[j]; x[j] = x[j+1]; x[j+1] = temp; } } } } int main() { FILE *in_file = fopen("input.txt", "r"); if (!in_file) { perror("Failed to open input file"); return 1; } // 动态管理单词数组:初始容量10,不够自动扩容 int capacity = 10; int word_count = 0; char **words = malloc(capacity * sizeof(char*)); if (!words) { perror("Failed to allocate memory for words"); fclose(in_file); return 1; } char buffer[256]; // 假设单个单词不超过255字符,可根据需求调整 while (fscanf(in_file, "%s", buffer) != EOF) { // 扩容检查:当单词数达到容量时,将容量翻倍 if (word_count >= capacity) { capacity *= 2; char **temp = realloc(words, capacity * sizeof(char*)); if (!temp) { perror("Failed to reallocate memory"); // 出错时清理已分配的内存 for (int i = 0; i < word_count; i++) free(words[i]); free(words); fclose(in_file); return 1; } words = temp; } // 复制单词到动态内存 words[word_count] = strdup(buffer); if (!words[word_count]) { perror("Failed to duplicate word"); // 清理资源 for (int i = 0; i < word_count; i++) free(words[i]); free(words); fclose(in_file); return 1; } word_count++; } fclose(in_file); // 排序:也可以替换成更高效的qsort // qsort(words, word_count, sizeof(char*), (int (*)(const void*, const void*))strcmp); arrange(word_count, words); // 写入输出文件 FILE *out_file = fopen("output.txt", "w"); if (!out_file) { perror("Failed to open output file"); for (int i = 0; i < word_count; i++) free(words[i]); free(words); return 1; } for (int i = 0; i < word_count; i++) { fprintf(out_file, "%s\n", words[i]); free(words[i]); // 写完即释放单个单词内存 } free(words); // 释放指针数组 fclose(out_file); return 0; }
额外优化建议
- 用
qsort替代自定义排序:标准库的qsort是经过优化的快速排序,比手动写的冒泡排序效率高很多,尤其当单词数量大的时候。 - 处理超长单词:如果输入的单词可能超过256字符,建议用
fgets配合strtok来读取和分割,避免缓冲区溢出。 - 内存泄漏检查:可以用Valgrind工具(Code::Blocks可以配置)检查程序的内存泄漏情况,确保所有动态分配的内存都被正确释放。
内容的提问来源于stack exchange,提问作者AestheticCode
相关产品推荐
相关产品推荐

