首页 > 解决方案 > 文件溢出到分配的内存 C

问题描述

我正在尝试用 C 编写一个基本的突变测试脚本,但我遇到了一些似乎无法解决的错误。首先要评论的是,在似乎有问题的函数namr中,我尝试尝试使用简单的凯撒密码来命名我正在创建的文件,以避免文件名中包含不需要的字符。当我按原样运行它时,似乎字符串cexpmcexp有时会从我正在另一个函数switchr中读取的文件中获取内容。当我在 Annotation 1 添加 printf 时,它似乎运行良好,但文件名出现错误。不过,如果我将注释 1 注释掉,则会出现malloc(): 损坏的顶部大小错误。我尝试了各种打印,看看有什么问题。到注释 2 时,cexpmcexp仍然是所需的长度和内容,但是到注释 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;
}

标签: cstringiomalloc

解决方案


你永远不会零终止字符串cexpcmexp. 所以添加这两行:

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 的条件可能不是您想要的。


推荐阅读