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

使用struct与动态内存分配统计文本单词词频的代码问题咨询

代码存在的问题汇总

1. 核心逻辑错误

  • 匹配到重复单词后直接return count,会直接终止整个文件读取流程,仅能处理到第一个重复单词之前的内容,完全不符合统计全文件单词频率的需求。
  • 该分支下没有释放临时申请的lower内存,会直接造成内存泄漏。

2. 输入读取逻辑错误

  • fscanf读取到文件末尾时返回EOF(值为负,非0),当前while (fscanf(f_in, "%s", word))的判断条件会把文件结束也判定为真,进入死循环,应当改为while (fscanf(f_in, "%s", word) == 1),仅当成功读取到1个字符串时才进入循环。
  • 没有对s数组的容量做边界判断,当单词数量超过数组最大长度时会发生数组越界写,触发内存溢出。

3. 未定义行为风险

  • tolower的入参需要强制转为unsigned char类型,否则遇到负值的扩展ASCII字符会触发未定义行为。
  • 新单词的freq初始化直接用++操作,若s数组是栈上申请或malloc申请未初始化,初始值为随机值,统计结果完全错误,应当改为s[count].freq = 1。
  • 当前lower的字符串终止符完全依赖calloc初始化为0的特性,如果后续换成malloc没有手动补'\0',strcmp、strcpy操作都会触发未定义行为。

malloc与calloc的选择、内存释放规则

选型建议

  • 如果你申请内存后需要内容默认初始化为0(比如字符串自动带终止符、计数变量初始为0),直接用calloc更省心,不需要额外手动初始化。
  • 如果你申请后会立即覆盖所有内存内容,不需要初始值,用malloc性能略高(省去了批量清0的开销),本案例中你如果用malloc申请lower,需要在循环转小写后手动加lower[strlen(word)] = '\0'补字符串终止符。

释放时机

  • 临时使用的动态内存(比如本案例中的lower),在当前作用域内所有用到该内存的逻辑都执行完成后即可释放,本案例需要在匹配到重复单词的分支里,s[j].freq++之后先加free(lower),再return,避免泄漏。
  • 存储统计结果的动态内存(如果你后续把固定大小的s数组改成动态扩容、把struct里的固定大小word改成动态申请的char*),需要在整个统计逻辑全部完成、业务侧不再需要统计结果之后,先遍历释放每个struct里的word内存,再释放struct数组本身的内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 01:06:06