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

C语言变异测试脚本malloc堆损坏 分配内存被文件内容溢出

问题根因与修复方案

核心错误点

  • 字符串未添加结束符:namr函数中,你为cexp、cmexp申请了长度+1的内存,但遍历赋值完成后,没有手动在末尾添加'\0'作为C字符串的结束标记。后续调用printf("%s")、strlen()、sprintf()等操作时,都会从字符串起始位置一直读到内存中随机出现的'\0'为止,因此会读到后续内存区域的其他内容(就是你看到的其他函数读取的文件内容),内存越界进一步破坏了malloc的堆结构,就会触发malloc(): corrupted top size崩溃。保留Annotation1的printf能暂时不崩溃只是巧合,因为printf执行后在内存里留下的随机字节刚好有个'\0',本质还是未定义行为。
  • 次要错误点1:countr函数中变量c未初始化就进入while(c != EOF)判断,且c应该定义为int类型而非char:因为EOF是值为-1的int常量,如果你的编译器默认char是无符号类型,c永远不可能等于EOF,会导致死循环、读取内容错误。
  • 次要错误点2:switchr函数中malloc的buffer没有free,存在内存泄漏;countr、switchr中调用fopen没有判断返回值,如果目标文件不存在会触发空指针访问崩溃。

修复代码

1. 修复namr函数的字符串结束符问题

只需要在两个遍历赋值循环结束后,分别给两个字符串末尾加'\0':

for (int i = 0; i < explen; i++) {
   cexp[i]= (exp[i] ? 'A' + exp[i] % 25 : exp[i]);
   printf("%d - %c - %c\n", i, exp[i], 'A' + exp[i] % 25);
//ANNOTATION 2
}
cexp[explen] = '\0'; // 新增这行
for (int i = 0; i < mexplen; i++) {
   cmexp[i]= (mexp[i] ? 'A' + mexp[i] % 25 : mexp[i]);
}
cmexp[mexplen] = '\0'; // 新增这行

2. 修复countr函数的c变量问题

int countr(char *filename, char *exp) {
    int out = 0;
    int i, flag;
    int inlen = strlen(exp);
    int c; // 改为int类型
    FILE *f = fopen(filename, "r");
    if (!f) return 0; // 新增fopen判空
    c = getc(f); // 先读第一个字符再进入循环
    while (c != EOF) {
        for (i = 0, flag = 0; i < inlen; i++) {
            if (exp[i] != c) {
                flag = 1;
                break;
            }
            c = getc(f);
        }
        if (flag == 0)
            out++;
        c = getc(f);
    }
    fclose(f);
    return out;
}

3. 补充switchr的内存释放与判空

在switchr函数末尾return outname;之前加一行free(buffer);,同时所有fopen调用后都增加空指针判断即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 20:36:09