How to clone a NIF resource

Hi All,

I’m trying to clone a NIF resource like this:


/* some code */

struct array_t *arr = (struct array_t *) enif_alloc_resource(ARRAY_RESOURCE, sizeof(struct array_t));

/* init the arr structure here */

ERL_NIF_TERM res1 = enif_make_resource(env, arr);
enif_release_resource(arr);

ERL_NIF_TERM res2 = enif_make_resource(env, arr);
enif_release_resource(arr);

return (enif_make_tuple(env, res1, res2));

But res1 and res2 are equal.
What i’d like to achieve here it to get two different resources (res1 =/= res2) pointing to the same array_t in memory.

Is that possible? If yes … how?

N.B: this is an experiement, please don’t tell me why :slight_smile:

No, you cannot do that. The documentation says
“Two resource terms will compare equal if and only if they would yield the same resource object pointer when passed to enif_get_resource”.

To get two different resources (res1=/=res2) you need to do two enif_alloc_resource calls.

You can of course solve it by introducing an indirection of your own. Two enif_alloc_resource blocks each with a pointer to the same array_t allocated with enif_alloc for example. And then do your own memory management of that array_t block with reference counting or whatever.

One more thing.
Your code example is buggy. The second call to enif_release_resource is wrong.

“Each call to enif_release_resource must correspond to a previous call to enif_alloc_resource or enif_keep_resource. References made by enif_make_resource can only be removed by the garbage collector.”

If you run that code, you may get a premature deallocation of the resource while one of res1 or res2 is still referring it.

@sverker Thanks for the clarification