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

Huffman加密C程序运行无限循环问题排查求助

Huffman加密程序无限循环问题排查与修复

以下是导致程序无限循环及其他关键问题的根源,以及对应的修复方案:


1. 优先队列移除函数(qremove)逻辑错误

这是引发无限循环的核心原因:原函数的循环体仅在特定条件下移动节点,否则没有任何处理,导致队列堆结构彻底混乱,后续的节点插入/移除操作无法正常终止。

原错误代码

node qremove(){
    int i, l;
    node n = q[i = 1];
    if (qend < 2){
        return 0;
    }
    qend--;
    while ((l = i * 2) < qend){
        if (l + 1 < qend && q[l + 1]->frequency < q[l]->frequency){
            l++;
            q[i] = q[l];
            i = l;
        }
    }  
    q[i] = q[qend];
    return n;
}

修复后代码

node qremove(){
    int i, l;
    node n = q[i = 1];
    if (qend < 2){
        return 0;
    }
    qend--;
    node last = q[qend]; // 取出队列最后一个节点准备下沉
    while ((l = i * 2) < qend){
        // 选择子节点中频率更小的那个
        if (l + 1 < qend && q[l + 1]->frequency < q[l]->frequency){
            l++;
        }
        // 当前节点频率小于等于子节点,停止下沉
        if (last->frequency <= q[l]->frequency){
            break;
        }
        // 子节点上移,更新当前索引
        q[i] = q[l];
        i = l;
    }
    q[i] = last; // 将最后一个节点放到正确位置
    return n;
}

2. importFile中编码生成函数调用时机错误

原代码在构建Huffman树的循环中,每次插入新节点就调用buildCode,这会重复生成编码,导致编码数组混乱,甚至引发递归逻辑异常。正确的做法是在Huffman树完全构建完成后,仅调用一次编码生成函数。

原错误代码片段

while (qend > 1){
    qinsert(newNode(0, 0, qremove(), qremove()));
    buildCode(q[1], s, 0); // 错误:循环内重复调用
}

修复后代码片段

while (qend > 1){
    qinsert(newNode(0, 0, qremove(), qremove()));
}
buildCode(q[1], s, 0); // 树构建完成后统一生成编码

3. 字符读取的类型错误

fgetc返回int类型(用于区分字符值和EOF),原代码用char接收会导致:当读取到0xFF(扩展ASCII字符)时,会被错误识别为EOF;同时input_data未累加,导致输入字节数统计错误。

原错误代码片段

char c;
while((c = fgetc(fp_in)) != EOF){
    frequency[(int)c]++;
    putchar(c);
}

修复后代码片段

int c; // 改为int类型存储fgetc返回值
printf("Read file: \n");
while((c = fgetc(fp_in)) != EOF){
    frequency[(unsigned char)c]++; // 转无符号避免负数索引
    putchar(c);
    input_data++; // 累加输入字节数
}

4. 字符输出的分支逻辑错误

printCode函数中,case '\n'缺少break,会导致执行完该分支后继续执行case ' '的代码,输出混乱。

原错误代码片段

case '\n':
    printf("\\n ");
case ' ':
    printf("\' \' ");
    break;

修复后代码片段

case '\n':
    printf("\\n ");
    break; // 添加break终止分支
case ' ':
    printf("\' \' ");
    break;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:26:05