0

根据我看到的奇怪行为,我猜测以下代码无效。我的问题是:下面创建的 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;
}
4

1 回答 1

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(in msg.data) 是否无效,一旦msgpack_sbuffer_free(buffer)被调用?

不,因为它与sbuffer(见上文)无关。

但是一旦msg被销毁它就无效了,即在create_static_msg_object函数的末尾,因为msg它是一个局部变量。

注意:在上面的代码中,你应该小心调用msgpack_unpacked_destroy(&msg),以便在解包时分配的内部内存被正确释放。通过这样做,msgpack 对象也被清零。

msgpack_object-在没有依赖关系的情况下分配堆的正确方法是什么?

我会说你有两个解决方案:

  1. 深度复制(最常见的情况):msg.data递归浏览对象并在您自己的堆分配结构中复制每条数据。如果您使用预期的预定义格式解压缩档案,这样做会更容易。
  2. msg内存维护:动态分配msgpack_unpacked *msg = malloc(sizeof(*msg));解压后的结构(调用者必须管理删除:这里再次使用msgpack_unpacked_destroy释放内部区域内存,然后释放msg指针。
于 2012-11-09T10:21:09.583 回答