Protobuf сообщение и memcpy внутри erlang nif

Я использую protobuf внутри функции nif (erlang nif) и мне нужно создать ресурс типа сообщения protobuf. Я написал что-то вроде этого:

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

Вопрос в том... допустимо ли копировать сообщение protobuf следующим образом, а при очистке просто отпустите его:

  delete pointer

? Кажется, что все здесь правильно, но я не уверен, потому что конструктор скопированного объекта не был вызван и, возможно, есть какая-то магия со статическими переменными и т. Д. Также... нужно ли мне вызывать CopyFrom после memcpy?

upd: MyClass - это класс C++, а не C

1 ответ

Решение

enif_alloc_resource, enif_release_resource и enif_make_resource делают все управление памятью за вас. Вы можете сделать это несколько проще, указав тип ресурса указателем, и в этом случае вы вызываете delete из определенного вами деструктора ресурса (указатель функции, который вы передаете при вызове enif_open_resource_type).

Что касается того, что вы делаете с memcpy, то это небезопасно для сложных объектов. Например, если один из членов вашего класса является указателем на динамически распределенный ресурс, который он уничтожает в своем деструкторе, и вы запоминаете его, два объекта теперь совместно используют этот же ресурс. Когда один из объектов уничтожается (выпадает из области видимости, оператор удаления), другой объект остается с указателем на освобожденную память.

Вот почему вы определяете конструкторы копирования и присваивания, если у вас есть сложный класс. Я предполагаю, что CopyFrom должен быть и вашим назначением, и конструктором копирования.

Другие вопросы по тегам