[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Memory Allocation in Bison
From: |
Tim Van Holder |
Subject: |
Re: Memory Allocation in Bison |
Date: |
Tue, 06 Feb 2007 14:16:03 +0100 |
User-agent: |
Thunderbird 1.5.0.9 (Windows/20061207) |
Martin Bock wrote:
> Hi everybody,
>
>
> I have have a question concerning memory allocation for yyval in bison:
> I' looking for the memory reserved for yyval, how it is done and how
> much it is. In the .c-file generated by bison, I found yyval is of the
> type YYSTYPE. But I cannot find any information about the memory. Also,
> I found no about it in the help archive.
yylval is a stack variable - it is NOT dynamically allocated. It is
pushed (copied) onto a stack by bison. If your YYSTYPE contains a
char*, it gets the value you assign to it, nothing more nothing less.
Assigning yytext (as you may be doing) is a Bad Idea (because by the
time bison starts processing the values, the pointer into yytext may no
longer be valid, and if it's still valid, it's likely to be pointing to
different text). Assigning strdup(yytext) would be better.
> What it is all about:
>
> My parser is working direct on the bison-made variables (all those $$,
> $1...). It's like this:
> {...
> strcat($1, $2);
> $$ = $1;
> ...}
>
> Up to now, I had no problems with this. But I'm not sure: is it right to
> extend $1 this way, or am I doing some real big-memory-chaos-thing?
It depends on how $1 got its value. If $1 was set to some dynamically
allocated piece of memory large enough for both $1 and $2 (+ a NUL),
then this is not wrong (although you should consider freeing $2 if it
was dynamically allocated).
Otherwise, it's the equivalent of
char* s1 = strdup("foo");
char* s2 = strdup("bar");
strcat (s1, s2);
return s1;
> Is it wiser to do it this way:
> {...
> char *temp = malloc( (3+strlen($1)) );
> strcat(temp , $2);
> $$ = temp;
> ...}
Nope, it's almost as bad:
- it uses strcat on uninitialized raw memory
- it drops the value of $1 entirely
- it (sort of) assumes $2 is 2 characters long
Something like
foo
: bar xyzzy
{
/* Assumes neither $1 nor $2 are NULL, and that $$, $1, $2 are
* suitably declared to refer to a char* value. */
$$ = (char*) malloc (strlen ($1) + strlen ($2) + 1);
strcpy ($$, $1);
strcat ($$, $2);
}
;
would probably be safest.