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
相关产品推荐
相关产品推荐

