解压缩的msgpack_object是否依赖于解压缩的缓冲区?

时间:2012-11-07 21:49:05

标签: c msgpack

基于我所看到的奇怪行为,我猜测以下代码无效。我的问题是:下面创建的msgpack_object是否依赖于msgpack_sbuffer?也就是说,一旦msgpack_sbuffer_free(缓冲区)被调用,msgpack_object(在msg.data中)是无效的吗?如果是这样,在这种情况下,获取堆分配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;
}

1 个答案:

答案 0 :(得分:0)

- 下面创建的msgpack_object是否取决于msgpack_sbuffer

没有。您的msgpack_sbuffer仅用于打包时(msgpack_packer用于编写二进制序列化的增长缓冲区)。

相反,msgpack对象取决于msgpack_unpacked结构:

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

该对象与此结构密切相关,与此对象相关的动态内存(例如,如果它包含数组,地图等)由zone管理。

- 调用msgpack_object后,msg.datamsgpack_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指针。