0

Based on the bizarre behaviour I'm seeing, I'm guessing that the following code is not valid. My question is: does the msgpack_object created below depend on the msgpack_sbuffer? That is, is the msgpack_object (in msg.data) invalid, once msgpack_sbuffer_free(buffer) is called? If so, what's the correct way to get a heap allocated msgpack_object with no dependencies in this situation?

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;
}
brooks94
  • 3,836
  • 4
  • 30
  • 57

1 Answers1

0

- Does the msgpack_object created below depend on the msgpack_sbuffer?

No. Your msgpack_sbuffer is only used at packing time (it is the growing buffer used by msgpack_packer to write the binary serialization).

Instead the msgpack object depends on the msgpack_unpacked structure:

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

The object is closely related to this structure, and the dynamic memory related to this object (e.g. if it contains arrays, maps, etc) is managed by zone.

- Is the msgpack_object (in msg.data) invalid, once msgpack_sbuffer_free(buffer) is called?

No since it is not related to the sbuffer (see above).

But it is invalid as soon as msg is destroyed, i.e. at the end of the create_static_msg_object function since msg is a local variable.

Note: within the above code you should take care to call msgpack_unpacked_destroy(&msg) so that the internal memory allocated while unpacking is properly freed. By doing so the msgpack object is also zeroed out.

- What's the correct way to get a heap allocated msgpack_object with no dependencies?

I would say you have 2 solutions:

  1. Deep duplicate (most common case): browse the msg.data object recursively and duplicate each piece of data within your own heap allocated structure. Doing so is easier if you are unpacking an archive with an expected pre-defined format.
  2. Maintain msg on memory: allocate your unpacked structure dynamically (msgpack_unpacked *msg = malloc(sizeof(*msg));), init it, unpack it and return it to the caller so that you can use the related object at your convenience. The caller must manage deletion: here again use msgpack_unpacked_destroy to free up the internal zone memory then free your msg pointer.
deltheil
  • 15,496
  • 2
  • 44
  • 64