Question

I'm using protobuf inside nif function (erlang nif) and need to create resource of protobuf message type. I wrote something like this:

ERL_NIF_TERM create_resource(ErlNifEnv *env, const MyClass &msg)
{
    size_t size = sizeof(MyClass);

    MyClass *class = (MyClass *)enif_alloc_resource(MY_CLASS, size);

    memcpy(class, &msg, size);
    // class->CopyFrom(&msg);

    ERL_NIF_TERM term = enif_make_resource(env, class);
    enif_release_resource(class);

    return term;
}

The question is.. is it legal for the protobuf message to be copied like this and in cleanup just release it with:

  delete pointer

? Seems that everything is right here, but I'm not shure, cause the constructor of the copied object was not invoked and may be there is some magick with static vars and etc... Also.. do I need to call CopyFrom after memcpy?

upd: MyClass is C++ class not C

Was it helpful?

Solution

enif_alloc_resource, enif_release_resource, and enif_make_resource do all the memory management for you. You can make it somewhat easier by making your resource type a pointer, in which case you call delete from your defined resource destructor (the function pointer you pass when calling enif_open_resource_type).

As far as what you're doing with memcpy, it's not safe for complex objects. For instance, if one of your class members is a pointer to a dynamically allocated resource which it destroys in its destructor, and you memcpy it, two objects are now sharing that same resource. When one of the objects is destroyed (falling out of scope, delete operator), the other object is left with a pointer to freed memory.

This is why you define copy and assignment constructors if you have a complex class. I'm guessing CopyFrom should, in fact, be both your assignment and copy constructor.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top