使用enif_resource_alloc正确释放内存

时间:2013-01-28 02:31:17

标签: c erlang alloc

我编写了一个Erlang C NIF,它在调用new之后返回一个指向结构的指针,现在只是在insert上增加一个变量。我想知道如何正确销毁原始资源,或者至少将其标记为GC。我没有运气。

#include <stdio.h> 
#include "erl_nif.h"


typedef struct level {
    float a;
    float b;
} LVL;

// data array with key being the price
typedef struct book {
    int array_size; // # of TTL indices
    int len; // # of Occupied indices (inc. val) from bestPriceIndex
    int max_len; 

    LVL lvl_data[];

} Book;


static ErlNifResourceType *MEM_RESOURCE;


    static int
on_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info)
{
    ErlNifResourceFlags flags = (ErlNifResourceFlags)(ERL_NIF_RT_CREATE);

    if ( (MEM_RESOURCE = enif_open_resource_type(env, 
            NULL,
            "mem_resource", 
            NULL, //dtor
            flags, 
            NULL)) == NULL)
        return -1;

    return 0;
}


    static ERL_NIF_TERM 
new( ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[] ) 
{   
    int max_len = 50;

    int mem_size = sizeof(Book) + max_len * sizeof(LVL);
    Book *q = enif_alloc_resource(MEM_RESOURCE, mem_size );
        if( q == NULL ) return enif_make_string(env, "could not alloc", ERL_NIF_LATIN1);

    q->lvl_data[0].a = 7.0;     

    ERL_NIF_TERM term = enif_make_resource(env, q);

    enif_release_resource(q);

    return term;
};


    static ERL_NIF_TERM 
insert( ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[] ) 
{
    Book *p;
    if (!enif_get_resource(env, argv[0], MEM_RESOURCE, (void **)&p)) 
       return enif_make_badarg(env); 

    float x = ++p->lvl_data[0].a;

    return enif_make_string(env, "okk", ERL_NIF_LATIN1);
};


static ErlNifFunc nif_funcs[] = 
{ 
    {"new", 0, new},
    {"insert", 1, insert}
};

ERL_NIF_INIT( test, nif_funcs, on_load, NULL, NULL, NULL )

1 个答案:

答案 0 :(得分:1)

如果没有持有资源的条款,GC将自动收集资源