Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Is it going to leak or be a dangling pointer?
Forum Updated to NodeBB v4.3 + New Features

Is it going to leak or be a dangling pointer?

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 1.7k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Dohisev
    wrote on last edited by Dohisev
    #1

    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?

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      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.

      D 1 Reply Last reply
      2
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        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.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • Chris KawaC Chris Kawa

          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.

          D Offline
          D Offline
          Dohisev
          wrote on last edited by
          #4

          @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.

          Chris KawaC 1 Reply Last reply
          0
          • D Dohisev

            @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.

            Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @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.

            1 Reply Last reply
            3

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved