r22651 - gnucash/trunk/src - Guile 2: replace deprecated SCM_SYMBOL_CHARS function

Geert Janssens janssens-geert at telenet.be
Sat Dec 22 05:49:37 EST 2012

And just to complete my explanation, you are in fact using the 
scm_dynwind_* functions slightly differently from their intended use. In 
the example of gnc_scm_to_locale_string the net result is the same, but 
in locations where it matters you won't get the desired memory leak 
protection effect.

A minimal code snippet:

str = scm_to_locale_string(scm_string);
scm_dynwind_begin (0);
call_other_scm_function; /* potentially non-local exiting function */
scm_dynwind_free (str); /* wrong: too late */
scm_dynwind_end ();

What happens here is that call_other_scm_function may exit non-locally 
(for example because it triggers the error catch code internally). If 
that happens, scm_dynwind_free is never reached and str won't be freed.

scm_dynwind_free is not actually freeing memory itself, but it tells 
guile to free the memory whenever the dynwind context is left (locally 
by reaching scm_dynwind_end or non-locally). So this function should be 
called *before* calling any function that might exit non-locally. The 
proper invocation would be:

str = scm_to_locale_string(scm_string);
scm_dynwind_begin (0);
scm_dynwind_free (str); /* ok */
call_other_scm_function; /* potentially non-local exiting function */
scm_dynwind_end ();

In this case, str is first marked for freeing (but not freed yet !) 
whenever the context ends and only then the potentially non-local 
exiting function is called. In this case str is guaranteed to be freed: 
if other_scm_function succeeds, str will be freed once scm_dynwind_end 
is reached. If it fails the non-local exit is detected internally and 
str is freed then.

As said before, for gnc_scm_to_locale_string this didn't matter really, 
because g_strdup is never exiting non-locally from guile's point of view.

I hope this helps clearing it up.


More information about the gnucash-devel mailing list