Is it going to leak or be a dangling pointer?



  • I'm starting to use libvlc in a project and I noticed that they give me a pointer to everything, for example, for the core instance, for the media, for the media player, etc, and I find myself passing that pointer as parameter for a few methods around and I'm starting to wonder if it's not going to be leaking or become a dangling pointer.

    For example, the instance I need everywhere and that is the documentation: libvlc_new()

    They say I have to call libvlc_release(). The documentation: Decrement the reference count of a libvlc instance, and destroy it if it reaches zero.

    And here on this document they say this:

    LibVLC uses a certain number of objects. Each one maintains a references count, which is used to know when the object must be released. The three related functions are:

    • libvlc_object_name_new() Create an object with a refcount equal to 1.
    • libvlc_object_name_retain() Increment the object refcount by 1.
    • libvlc_object_name_release() Decrement the refcount by 1, and release the object if the new refcount is less than zero.

    Example:

    libvlc_media_list_t *p_ml = libvlc_media_list_new(libvlc_inst)
    
    /* Free the memory used by media_list release */
    libvlc_media_list_release(p_ml);
    

    Does that mean that I can pass those pointers without being worried about leaking of becoming a dangling pointer?


  • Moderators

    You need to keep in mind the lifetime when passing these pointers. The objects use reference counting so
    Creating an object with libvlc_new() sets a refcount to 1.
    Every call to libvlc_retain() increases it by 1.
    Every call to libvlc_release() decreases it by 1.
    Object is deleted when refcount drops to 0.

    So the rule is that number of calls to libvlc_new plus number of calls to libvlc_retain must be equal to number of calls to libvlc_release, otherwise the object leaks.
    As to dangling pointers - yes, that can happen too. If you pass that pointer somewhere, store it, and then make the refcount drop to 0 the object will be deleted and the pointer will become invalid.

    Usually when working with such low level memory management it's good to pack it into a "smart pointer".
    A super-basic implementation for this case could look something like this:

    class VLCInstancePointer()
    {
        libvlc_instance_t* ptr;
    public:
        VLCInstancePointer() : ptr(nullptr) {}
        VLCInstancePointer(libvlc_instance_t* p) : ptr(p) {}
        VLCInstancePointer(const VLCVLCInstancePointer& other) { ptr = other.ptr; libvlc_retain(ptr); }
        VLCInstancePointer& operator=(const VLCVLCInstancePointer& other) { libvlc_release(ptr); ptr = other.ptr; libvlc_retain(ptr); }
        ~VLCInstancePointer() { libvlc_release(ptr); }
        libvlc_instance_t* operator*() const { return ptr; }
    };
    

    This way you don't need to worry about leaks or dangling pointers. You just create it somewhere like this:

    VLCInstance ptr(libvlc_new());
    

    and you can pass it around by value. If it gets copied the refcount will increase. If it goes out of scope it will decrease. When the last instance goes out of scope it will decrease the refcount to 0 and the object will be deleted.

    If you don't want to use the refcounting provided by libvlc you can also use Qt's shared pointer:

    QSharedPointer<libvlc_instance_t> ptr(libvlc_new(), &libvlc_release);
    

    This will use Qt's refcounting for the object and when a last copy of QSharedPointer pointing to this instance goes out of scope it will call libvlc_release on the pointer.


  • Lifetime Qt Champion

    Hi,

    That's a question better asked on the libvlc forum. This is a Qt forum.

    From your example and their documentation, the p_ml pointer will be valid until you call libvlc_media_list_release unless there was a call somewhere to libvlc_media_list_retain without a matching libvlc_media_list_release on that object.



  • @Chris-Kawa Amazing example, thank you very much. It's better ti use QSharedPointer than creating a class to wrap the libvlc functions right? I think it's less things to worry about, I don't know, what is your opinion?

    @SGaist You are right, I asked it here actually cause I think that we can find good developers here, look at the answer I got, it's really nice from you guys.


  • Moderators

    @Dohisev said in Is it going to leak or be a dangling pointer?:

    It's better ti use QSharedPointer than creating a class to wrap the libvlc functions right? I think it's less things to worry about, I don't know, what is your opinion?

    Sure, especially since each function is actually called differently you would have to make a ton of these wrappers or make a template out of it which... brings you to how a shared pointer is implemented. No need to reinvent the wheel.
    Actually any shared pointer will do as long as it can take a custom deleter e.g. std::shared_ptr would work too.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.