help-bison
[Top][All Lists]
Advanced

[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.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]