0

nif関数(erlang nif)内でprotobufを使用しており、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

?すべてがここにあるようですが、私は確信が持てません。コピーされたオブジェクトのコンストラクターが呼び出されず、静的変数などの魔法がある可能性があります...また..memcpyの後にCopyFromを呼び出す必要がありますか?

upd:MyClassはCではなくC++クラスです

4

1 に答える 1

1

enif_alloc_resource、enif_release_resource、およびenif_make_resourceは、すべてのメモリ管理を行います。リソースタイプをポインタにすることで、多少簡単にすることができます。その場合は、定義済みのリソースデストラクタ(enif_open_resource_typeを呼び出すときに渡す関数ポインタ)からdeleteを呼び出します。

memcpyで行っていることに関しては、複雑なオブジェクトに対しては安全ではありません。たとえば、クラスメンバーの1つが動的に割り当てられたリソースへのポインタであり、そのリソースがデストラクタで破棄された場合、それをmemcpyすると、2つのオブジェクトが同じリソースを共有するようになります。オブジェクトの1つが破棄されると(スコープから外れる、演算子を削除する)、もう1つのオブジェクトには解放されたメモリへのポインタが残ります。

これが、複雑なクラスがある場合にコピーおよび割り当てコンストラクターを定義する理由です。実際、CopyFromは、割り当てとコピーコンストラクターの両方である必要があると思います。

于 2012-12-26T07:33:08.923 に答える