在YACC中分配字符串时出错

时间:2013-10-08 16:33:19

标签: c malloc yacc

我有这个Yacc代码:

...
%union{
    int counter;
    char* partial_code;
}
....
single_selection_predicate: STRING EQ SINGLE_QUOTATION STRING SINGLE_QUOTATION 
        {   $<counter>$ = 1;
            printf("Counter: %d\n", $<counter>$);
            int size = sizeof(char)*(strlen($<partial_code>1) + strlen($<partial_code>4) + 7);
            $<partial_code>$ = (char*)malloc(size);
            printf("Counter: %d\n", $<counter>$);}
        ;
....

我希望语法规则相关代码块中的第一个和第二个printf能够打印相同的输出。但是,我得到这样的东西:

Counter: 1
Counter: 7402224

可能正在发生一些溢出,但我无法弄清楚原因。你能帮帮我吗?

2 个答案:

答案 0 :(得分:1)

工会不是结构。

在您的联盟中,counterpartial_code占用相同的内存位置。 您对partial_code的写入会覆盖counter的作业。

%union{
    int counter;
    char* partial_code;
}

答案 1 :(得分:1)

为了扩展查理的答案,你可以很容易地将结构加入到联合中:

%union{
    struct {
        int counter;
        char* partial_code;
    } code_and_counter;
    char *partial_code;
}
%token<partial_code> STRING
%type<code_and_counter> single_selection_predicate
%%
single_selection_predicate: STRING EQ SINGLE_QUOTATION STRING SINGLE_QUOTATION 
    {   $$.counter = 1;
        printf("Counter: %d\n", $$.counter);
        int size = strlen($1) + strlen($4) + 7;
        $$.partial_code = malloc(size);
        printf("Counter: %d\n", $$.counter);}
    ;

此外,您应该很少使用$<tag>X语法 - 您应该始终如上所示声明令牌/非终端的类型,并让yacc将标签粘贴到您的操作代码中。

此外,永远不要使用sizeof(char)(它总是1),并且从不显式地转换malloc的结果。