How to properly free an erlang term

295 Views Asked by At

In the example erlang port program

tuplep = erl_decode(buf);
fnp = erl_element(1, tuplep);
argp = erl_element(2, tuplep);
...
erl_free_compound(tuplep);
erl_free_term(fnp);
erl_free_term(argp);

Both erl_free_compound and erl_free_term are used for freeing term (and its sub-term) separately of the same ETERM*. From the documentation of erl_free_compund() it says

erl_free_compound() will recursively free all of the sub-terms associated with a given Erlang term

So, my question is, does erl_element() makes a copy of the element which, if not freed separately will leak memory or the above situation might lead to double free which is detected and handled by erl_free_term.

1

There are 1 best solutions below

3
On

The erl_interface library indeed uses a sort of reference counting system to keep track of allocated ETERM structs. So if you write:

ETERM *t_arr[2]; 
ETERM *t1; 

t_arr[0] = erl_mk_atom("hello"); 
t_arr[1] = erl_mk_atom("world"); 
t1 = erl_mk_tuple(&t_arr[0],2); 

you have created three (3) Erlang terms (ETERM). Now if you call: erl_free_term(t1) you only free upp the tuple not the other two ETERM's. To free all the allocated memory, you would have to call:

erl_free_term(t_arr[0]); 
erl_free_term(t_arr[1]); 
erl_free_term(t1) 

To avoid all these calls to erl_free_term() you can use: erl_free_compund() instead. It does a "deep" free of all ETERM's. So the above could be accomplished with:

erl_free_compund(t1) 

Thus, this routine makes it possible for you to write in a more compact way where you don't have to remember the references to all sub-component ETERM's. Example:

ETERM *list; 

list = erl_cons(erl_mk_int(36), 
erl_cons(erl_mk_atom("tobbe"), 
erl_mk_empty_list())); 
... /* do some work */ 
erl_free_compound(list); 

Update: To check if you really free up all the create terms you can use this piece of code (original manual entry:

long allocated, freed;

erl_eterm_statistics(&allocated,&freed);
printf("currently allocated blocks: %ld\n",allocated);
printf("length of freelist: %ld\n",freed);

/* really free the freelist */
erl_eterm_release();

(answer adopted from here)