c - 文件溢出到分配的内存 C
问题描述
我正在尝试用 C 编写一个基本的突变测试脚本,但我遇到了一些似乎无法解决的错误。首先要评论的是,在似乎有问题的函数namr中,我尝试尝试使用简单的凯撒密码来命名我正在创建的文件,以避免文件名中包含不需要的字符。当我按原样运行它时,似乎字符串cexp和mcexp有时会从我正在另一个函数switchr中读取的文件中获取内容。当我在 Annotation 1 添加 printf 时,它似乎运行良好,但文件名出现错误。不过,如果我将注释 1 注释掉,则会出现malloc(): 损坏的顶部大小错误。我尝试了各种打印,看看有什么问题。到注释 2 时,cexp和mcexp仍然是所需的长度和内容,但是到注释 3 时,它们的长度为 26 或 25 个字符,并且包括我正在阅读的文件的起始行脚本的其他部分。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *namr(char *exp, char *mexp, int ignv) {
int explen = strlen(exp);
int mexplen = strlen(mexp);
//printf("EXPLEN: %d MEXPLEN: %d\n",explen,mexplen);
//ANNOTATION 1
char *cexp = (char *)malloc(explen + 1);
char *cmexp = (char *)malloc(mexplen + 1); //Exp in Caeser Cipher
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
}
for (int i = 0; i < mexplen; i++) {
cmexp[i]= (mexp[i] ? 'A' + mexp[i] % 25 : mexp[i]);
}
printf("EXP: %s\nMEXP: %s\n", exp, mexp);
printf("CEXP: %s\nCMEXP: %s\n", cexp, cmexp);
//ANNOTATION 3
printf("%s - %d\n%s - %d\n%d\n", cexp, strlen(cexp),
cmexp, strlen(cmexp), strlen("./U_SWITCH_MTNTS/TO%03.c"));
char *outname = (char *)malloc((30 + explen + mexplen));
sprintf(outname, "./U_SWITCH_MTNTS/%sTO%s%03d.c", cexp, cmexp, ignv);
free(cexp);
free(cmexp);
return outname;
}
int countr(char *filename, char *exp) {
int out = 0;
int i, flag;
int inlen = strlen(exp);
char c;
FILE *f = fopen(filename, "r");
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;
}
char *switchr(char *filename, char *exp, char *mexp, int ignv) {
int i, flag,buffcount;
FILE *f = fopen(filename, "r");
char *outname = namr(exp, mexp, ignv);
FILE *fout = fopen(outname, "w");
char c = getc(f);
int ignc = ignv;
int inlen = strlen(exp);
char *buffer = (char *)malloc(inlen * sizeof(char));
while (c != EOF) {
for (i = 0, flag = 0, buffcount = 0; i < inlen; i++) {
if (exp[i] != c) {
flag = 1;
break;
} else {
buffer[buffcount] = c;
buffcount++;
c = getc(f);
}
}
if (flag == 0) {
if(ignc == 0) {
fputs(mexp, fout);
} else {
for (i = 0; i < buffcount; i++)
fputc(buffer[i], fout);
}
ignc--;
} else {
for (i = 0; i < buffcount; i++)
fputc(buffer[i], fout);
}
fputc(c, fout);
c = getc(f);
}
fclose(f);
fclose(fout);
return outname;
}
void mstrswitch(char *filename) {
int ecount = countr(filename, "==");
char **filenames = (char **)malloc(5 * ecount * sizeof(char *));
char command[100];
system("mkdir U_SWITCH_MTNTS");
system("mkdir TEST_OBJECTS");
for (int i = 0;i < ecount; i++) {
filenames[5 * i] = switchr("test.c", "==", "<=", i);
filenames[5 * i + 1] = switchr("test.c", "==", ">=", i);
filenames[5 * i + 2] = switchr("test.c", "==", ">", i);
filenames[5 * i + 3] = switchr("test.c", "==", "<", i);
filenames[5 * i + 4] = switchr("test.c", "==", "!=", i);
}
for (int i = 0; i < 5 * ecount; i++) {
sprintf(command, "gcc -o ./TEST_OBJECTS/test%03d %s", i, filenames[i]);
system(command);
sprintf(command, "./TEST_OBJECTS/test%03d", i);
system(command);
free(filenames[i]);
}
free(filenames);
}
int main() {
mstrswitch("test.c");
return 0;
}
解决方案
你永远不会零终止字符串cexp
和cmexp
. 所以添加这两行:
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);
}
cexp[explen]= '\0'; <------------------- add
for(int i=0;i<mexplen;i++)
{
cmexp[i]= (mexp[i]?'A'+mexp[i]%25: mexp[i]);
}
cmexp[mexplen]= '\0'; <------------------- add
除此之外,以下行看起来很奇怪:
cexp[i]= (exp[i]?'A'+exp[i]%25: exp[i]);
^^^^^^
Always true
具有始终返回 true 的条件可能不是您想要的。
推荐阅读
- reactjs - react native 中的 FlatList 正在渲染但不显示文本
- javascript - 在javascript(React)中使用特定键反转对象数组的问题
- r - 插入符号中带有 search = 'random' 选项的 tuneLength 参数不起作用
- javascript - 组件的多个导航链接使用 reactjs 呈现每次点击
- r - 是否有 R 函数来统计比较不同的集群解决方案?(例如,使用 pam/clara 解决方案的 k-means 解决方案)
- scala - 如何使用 Circe 解析动态 JSON
- javascript - 为什么没有为此 MediaStreamTrack 触发“结束”事件?
- azure - 如何使用 powershell 查询“Azure 状态”
- python - 如何在图上返回直接依赖的节点
- visual-c++ - 为什么我会收到致命错误 C1075,我检查了代码并没有出错