C字符串截断的bug

时间:2013-04-22 12:31:24

标签: c string yacc

我正在从事关于语法分析的学校课程。目标是创建一个小语言,以便使用cairo库创建矢量图形。我们选择在C中使用中间媒体状态。

我们使用Yacc生成一个由gcc编译的C代码。它工作正常,但我对字符串有一些问题。

这是代码使用:

        int sumChar = 0 ;

        char outnb1[20];
        char outnb2[20];

        sprintf(outnb1, "%f;", $4);
        sprintf(outnb2, "%f;", $8);

        sumChar = (6+strlen($2)+1+5+strlen($2)+1+strlen(outnb1)+strlen($6)+strlen($7)+strlen(outnb2)+strlen($10)+strlen($11)+1+1+strlen($14)+1);

// $ 14 is the string returned by another part of the code.

        printf("String = %s\nSIZE = %d\n",$14,strlen($14));

//The printf here is exact and the string is not truncated :
//cairo_line_to ( cr ,prevPoint[0] ,prevPoint[1]);
//cairo_move_to ( cr ,prevPoint[0] ,prevPoint[1]);

        char *result = malloc(sizeof(char)*sumChar);
        sprintf(result, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s","\n\nint ",$2,";","\nfor(",$2,"=",outnb1,$6,$7,outnb2,$10,$11,")","{",$14,"}");
        printf("String after sprintf = %s\nSIZE = %d\n",$14,strlen($14));

//The printf print something like :
//cairo_line_to ( cr ,prevPoint[0] ,prevPoint[1]);
//cairo_move_to ( cr ,prevPoint[0]�

        $$ = result;

我真的不明白为什么在malloc之后字符串会被截断。它显然是一个记忆错误,但我不知道为什么。任何想法或解决方案?

编辑:

Yacc规则:

%union
{
    double number;
    char * str;
};

%token DRAW <number>NB <str>COMP <str>VARNAME <str>VARFOR <str>INC;
%type <str>D;
%type <str>BLOCFOR;
%type <str>FOR;

FOR : '(' VARFOR '=' NB ';' VARFOR COMP NB ';' VARFOR INC ')' '{' BLOCFOR '}' 
    {
        int sumChar = 0 ;
        char outnb1[20];
        char outnb2[20];
        sprintf(outnb1, "%f;", $4);
        sprintf(outnb2, "%f;", $8);
        sumChar += (6+strlen($2)+1+5+strlen($2)+1+strlen(outnb1)+strlen($6)+strlen($7)+strlen(outnb2)+strlen($10)+strlen($11)+1+1+strlen($14)+1);
        printf("VALUE OF BLOCFOR = %s\nSIZE = %d\n",$14,strlen($14));

        char *result = malloc(sizeof(char)*(sumChar+1));
        sprintf(result, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s","\n\nint ",$2,";","\nfor(",$2,"=",outnb1,$6,$7,outnb2,$10,$11,")","{",$14,"}");
        printf("VALUE OF BLOCFOR AFTER RESULT = %s\nSIZE = %d\n",$14,strlen($14));
        printf("%s\n",result );
        $$ = result;
    }

BLOCFOR : DRAW D '$' {$$ = $2; printf("INSIDE BLOCFOR %s\nSIZE = %d\n",$2,strlen($2));}

我希望它有所帮助。我无法提供正常工作的代码,因为它需要一个简化的lex文件。 Howewer我可以这样说:

char result[sumChar];

result是正确的,但$$ = result无法正常工作(我无法使用FOR FOR返回的值只是随机字符,如�G�+ 0 IFI)

这是在lex源中解析和返回str值:

<FOR>[[:alpha:]]+ {yylval.str = strdup(yytext);return VARFOR;}

解决:问题解决了,这是一个糟糕的sumChar计算和D标记内的分配。

1 个答案:

答案 0 :(得分:0)

变量sumChar不包含终止+1字符的额外'\0'。这很可能最终导致未定义的行为,其中您的问题可能是其症状。将其添加到sumCharmalloc来电。