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

如何修复count_words()函数以生成正确词频的单词链表?

C语言词频统计链表问题排查与修复

核心问题根源

你的问题集中在两个关键点:

  1. 单词内存复用导致内容覆盖:你大概率使用了同一个局部字符缓冲区读取所有单词,直接将缓冲区地址赋值给链表节点的word指针。所有节点的word会指向同一块内存,后续读取的单词会覆盖之前的内容,函数返回后局部缓冲区被释放,最终word指针变成野指针(表现为空)。
  2. 链表节点插入逻辑错误:全局变量word_counts最终仅存1个节点、count为6,说明你没有正确创建并链入新节点,而是一直在修改同一个节点的count值,新节点从未被添加到链表中。

具体修复步骤

1. 为每个单词独立分配内存

不要直接把缓冲区地址赋值给节点的word,必须为每个单词单独分配内存并复制内容:

// 错误写法:直接复用缓冲区指针
node->word = word;

// 正确写法1:使用strdup(POSIX标准,Windows可用_strdup)
node->word = strdup(word);
if (node->word == NULL) {
    perror("strdup failed");
    exit(EXIT_FAILURE);
}

// 正确写法2:手动malloc+strcpy(兼容所有环境)
node->word = malloc(strlen(word) + 1);
if (node->word == NULL) {
    perror("malloc failed");
    exit(EXIT_FAILURE);
}
strcpy(node->word, word);

2. 修复链表节点插入逻辑

确保找到重复单词时累加count,未找到时创建新节点并链入链表:

// 示例:从全局链表word_counts中查找单词
WordCount *current = word_counts;
while (current != NULL) {
    if (strcmp(current->word, word) == 0) {
        current->count++;
        return; // 找到重复,直接返回
    }
    current = current->next;
}

// 未找到,创建新节点并头插
WordCount *new_node = malloc(sizeof(WordCount));
if (new_node == NULL) {
    perror("malloc failed");
    exit(EXIT_FAILURE);
}
new_node->word = strdup(word);
new_node->count = 1;
new_node->next = word_counts; // 新节点指向原链表头
word_counts = new_node; // 更新链表头为新节点

如果你的函数是通过指针参数操作链表(如void count_words(WordCount **wclist, FILE *fp)),则更新链表头时要写*wclist = new_node,确保传入的指针指向正确更新。

3. 验证全局变量初始化

确保全局变量word_counts初始化为NULL,避免野指针导致的异常:

WordCount *word_counts = NULL;

4. 内存泄漏防护(可选但推荐)

程序结束前遍历链表,释放每个节点的内存:

void free_wordcount(WordCount *head) {
    WordCount *temp;
    while (head != NULL) {
        temp = head;
        head = head->next;
        free(temp->word);
        free(temp);
    }
}

总结

按照上述步骤修复后,每个节点的word会指向独立的内存块,不会被后续单词覆盖;新节点也会正确链入链表,词频统计结果就能符合预期。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 07:37:48