基于我所看到的奇怪行为,我猜测以下代码无效。我的问题是:下面创建的msgpack_object是否取决于msgpack_sbuffer?也就是说,一旦调用了msgpack_sbuffer_free(buffer),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;
}

最佳答案

-下面创建的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_objectmsg.data(在msgpack_sbuffer_free(buffer)中)是否无效?

否,因为它与sbuffer不相关(请参见上文)。

但是一旦msg被销毁,即在create_static_msg_object函数的末尾,由于msg是局部变量,因此它是无效的。

注意:在上面的代码中,应小心调用msgpack_unpacked_destroy(&msg),以便正确释放在拆包时分配的内部存储器。这样,msgpack对象也将清零。

-获得没有依赖性的msgpack_object堆的正确方法是什么?

我会说您有2个解决方案:


深度重复(最常见的情况):递归浏览msg.data对象,并在自己的堆分配结构中重复每个数据。如果要以预期的预定义格式解压缩归档文件,则这样做更容易。
保持msg在内存上:动态分配已解压缩的结构(msgpack_unpacked *msg = malloc(sizeof(*msg));),将其初始化,解压缩并将其返回给调用方,以便您可以方便地使用相关对象。调用者必须管理删除操作:在此再次使用msgpack_unpacked_destroy释放内部区域内存,然后释放msg指针。

关于c - 解压缩的msgpack_object是否取决于解压缩它的缓冲区?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13278844/

10-15 02:15