[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: %destructor
From: |
Hans Aberg |
Subject: |
Re: %destructor |
Date: |
Sat, 27 Sep 2014 00:23:37 +0200 |
> On 26 Sep 2014, at 21:58, Bob Rossi <address@hidden> wrote:
>
> On Fri, Sep 26, 2014 at 03:37:18PM +0200, Hans Aberg wrote:
>>> The %destructor for result and result_list does not call free, but
>>> instead calls gdbmi_result_free. gdbmi_result_free free's the result
>>> (including the variable member of the result), and the result's next
>>> pointer, and so on.
>>>
>>> Is it correct for me to call gdbmi_result_free($$) instead of free($$)?
>>
>> The %destructor is for making C style cleanup during an error recovery: the
>> Bison generated parser will then skip forward, bypassing any normal
>> deallocations in the actions. So first write the parser in normal C style,
>> with deallocators in each instance matching the allocator used in the
>> actions. Then add %destructor if needed for the error recovery.
>
> Unfortunately, this confused me more than clarified things.
>
> What are the 'normal deallocations in the actions?' I only ever put
> allocations in the actions, never deallocations.
Then it will leak for everything that you do no deallocate during normal,
error-free parsing.
> In the second sentence you mentioned I should write deallocators in each
> instance matching the allocator used in the actions. THEN add
> %destructor if needed for error recovery.
>
> Where do I put deallocators in the bison generator parser, besides
> %destructor?
I am normally using C++, which is doing the cleanup, but let’s try C
(pseudocode):
list:
"[“ sequence[x] "]" { $$ = $x; }
;
sequence:
item[x] { $$ = make_list1($x); free($x); }
| sequence[s] "," item[x] { $$ = make_list($s, $x); free($s); free($x); }
;
In the first rule “list”, the pointer is reused, so no deallocation is needed.
In the “sequence” rules, the functions make_list1() and make_list() are
supposed to allocate a new list object, but not deallocate the pointers they
get. So then the pointers $x and $s will not be used anymore, and must be
deallocated in order to not leak.
> All of this side stepped the original question. Sorry if I was unclear.
> The question I was asking is, should I call free() or list_free() in
> the %destructor for a list.
The deallocator must always match the allocator used to create the element,
otherwise the result is undefined. So if you have an allocator for a list that
must list_free(), and that is what $$ holds, then this is the deallocator you
must use. And this is only to prevent leaks during error recovery.