4

在示例erlang 端口程序中

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);

erl_free_compound 和 erl_free_term 都用于释放相同 ETERM* 的术语(及其子术语)。从 erl_free_compund() 的文档中它说

erl_free_compound() 将递归地释放与给定 Erlang 术语相关的所有子术语

所以,我的问题是,erl_element() 是否会复制元素,如果不单独释放会泄漏内存,或者上述情况可能导致双重释放,由 erl_free_term 检测和处理。

4

1 回答 1

3

erl_interface库确实使用了一种引用计数系统来跟踪分配的 ETERM 结构。所以如果你写:

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); 

您已经创建了三 (3) 个 Erlang 术语 (ETERM)。现在,如果您调用: erl_free_term(t1) 您只会释放元组而不是其他两个 ETERM。要释放所有分配的内存,您必须调用:

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

为了避免所有这些对 erl_free_term() 的调用,您可以使用: erl_free_compund() 代替。它没有所有 ETERM 的“深度”。所以上面可以通过以下方式完成:

erl_free_compund(t1) 

因此,此例程使您可以以更紧凑的方式编写,您不必记住对所有子组件 ETERM 的引用。例子:

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); 

更新:要检查您是否真的释放了所有创建条款,您可以使用这段代码(原始手动条目

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();

从这里采用的答案

于 2013-06-21T04:59:33.803 回答