You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:51:40