在示例erlang port程序
中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()是否制作了元素的副本,如果没有单独释放会泄漏内存或上述情况可能会导致erg_free_term检测和处理的双重释放。
答案 0 :(得分: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)你只释放upp元组而不是 另外两个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);
更新:要检查您是否真的释放了所有创建条款,可以使用这段代码(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();