Search code examples
c++memory-managementmsgpack

What and When needs to be cleaned up when using msgpack-c?


I am using Msgpack-c. One thing that is not clear to me, is how to correctly handle memory when using this library. The quickstart examples declare everything locally and I presume rely on destructors being called when the application ends, but I cannot rely on the same.

Take the following:

    msgpack::unpacked msgunpacked;
    msgpack::unpack(&msgunpacked, msgdata, msglength);
    T params = msgunpacked.get().as<T>();
    return params ;

When is it safe to delete msgdata? After unpack()? After the conversion to T?

When is it safe to delete msgunpacked? After get()?

Do I need to delete or free params? And do I need to destroy members like msgpack::type::raw_ref explicitly?


Solution

  • When is it safe to delete msgdata? After unpack()? After the conversion to T?

    When you use msgpack::unpack() function, the default unpacking behavior is copy. So you can destroy msgdata after msgpack::unpack() is called.

    See memory management

    You can customize the behavior of copy. When you pass unpack_reference_func handler to msgpack::unpack(), and when the handler returns true, msgpack::unpacked might refer to msgdata. You can check the reference status via referenced parameter. If the reference parameter is set to true, the msgpack::unpacked refers to msgdata.

    void unpack(
        object_handle& result,
        const char* data,
        std::size_t len,
        bool& referenced, // actual status for reference
        unpack_reference_func f = nullptr, // customize copy/reference behavior
        void* user_data = nullptr,
        unpack_limit const& limit = unpack_limit());
    

    Strictly speaking, msgpack::unpacked doesn't refer to msgdata directly, msgpack::object that is held by msgpack::unpacked refers to msgdata.

    When is it safe to delete msgunpacked? After get()?

    See accessing unpacked data

    get() is the member function for getting msgpack::object. The msgpack::object is located on msgpack::zone, a kind of memory pool. And msgpack::unpacked contains std::unique_ptr<msgpack::zone>. That means you need to keep the lifetime of msgunpacked during you access the msgpack::object that is gotten by get(). If you convert to T from msgpack::object, and the T doesn't refer to msgpack::object, and you don't access msgpack::object any more, then you can destroy msgunpacked. I said that the T doesn't refer to msgpack::object. It depends on the type of T. Most of the types do not refer to msgpack::object. msgpack::type::raw_ref, boost::string_ref, and msgpack::type::variant_ref refer to msgpack::object.

    If you convert to those types, you need to keep the lifetime of msgpack::object.

    See conversion , adaptor , variant_ref

    Do I need to delete or free params?

    No. T is located on the stack, you don't need to free it. If T contains the data on the heap like as std::vector<sometype>, the data should be freed by the destructor of the T.

    And do I need to destroy members like msgpack::type::raw_ref explicitly?

    No, you don't need to free msgpack::type::raw_ref. It is just a reference type object. The memory that is referred by msgpack::type::raw_ref is freed when msgunpacked is freed.