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.

Geert
_______________________________________________
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to