0

私が見ている奇妙な動作に基づいて、次のコードは無効であると推測しています。私の質問は: 以下で作成された msgpack_object は msgpack_sbuffer に依存していますか? つまり、msgpack_sbuffer_free(buffer) が呼び出されると、(msg.data 内の) msg​​pack_object は無効になりますか? もしそうなら、この状況で依存関係のない msgpack_object を割り当てられたヒープを取得する正しい方法は何ですか?

msgpack_object create_static_msg_object() {
  msgpack_sbuffer* buffer = msgpack_sbuffer_new();
  msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);


  // does some calls to msgpack_pack_*() here

  msgpack_unpacked msg;
  msgpack_unpacked_init(&msg);

  msgpack_unpack_next(&msg, buffer->data, buffer->size, NULL);

  /* cleaning */
  msgpack_sbuffer_free(buffer);
  msgpack_packer_free(pk);

  return msg.data;
}
4

1 に答える 1

0

-msgpack_object以下に作成されたものは に依存しmsgpack_sbufferますか?

いいえ。Yourmsgpack_sbufferはパッキング時にのみ使用されます (msgpack_packerバイナリ シリアライゼーションを書き込むために使用される成長バッファです)。

msgpack_unpacked代わりに、msgpack オブジェクトは構造に依存します。

typedef struct msgpack_unpacked {
    msgpack_zone* zone;
    msgpack_object data;
} msgpack_unpacked;

オブジェクトはこの構造体と密接に関連しており、このオブジェクトに関連する動的メモリ (たとえば、配列、マップなどを含む場合) は によって管理されzoneます。

- msgpack_object(in msg.data) は無効ですか、一度msgpack_sbuffer_free(buffer)呼び出されますか?

いいえ、sbuffer(上記を参照) とは関係がないためです。

msgしかし、が破棄されるとすぐに、つまりcreate_static_msg_object関数の最後では無効になります。これmsgは、ローカル変数であるためです。

msgpack_unpacked_destroy(&msg)注: 上記のコード内で、アンパック中に割り当てられた内部メモリが適切に解放されるように注意して呼び出す必要があります。そうすることで、msgpack オブジェクトもゼロになります。

msgpack_object-依存関係なしで割り当てられたヒープを取得する正しい方法は何ですか?

2つの解決策があると思います:

  1. 深い複製 (最も一般的なケース):msg.dataオブジェクトを再帰的に参照し、独自のヒープ割り当て構造内で各データを複製します。予想される事前定義された形式でアーカイブを解凍する場合、これは簡単です。
  2. msgメモリ上で維持する: アンパックされた構造体を動的に割り当て ( msgpack_unpacked *msg = malloc(sizeof(*msg));)、初期化し、アンパックして呼び出し元に返すことで、関連するオブジェクトをいつでも使用できるようにします。呼び出し元は削除を管理する必要があります。ここでも、 を使用msgpack_unpacked_destroyして内部ゾーン メモリを解放し、msgポインタを解放します。
于 2012-11-09T10:21:09.583 に答える