Solved 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?
-
You need to keep in mind the lifetime when passing these pointers. The objects use reference counting so
Creating an object withlibvlc_new()
sets a refcount to 1.
Every call tolibvlc_retain()
increases it by 1.
Every call tolibvlc_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 tolibvlc_retain
must be equal to number of calls tolibvlc_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. -
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 calllibvlc_media_list_release
unless there was a call somewhere tolibvlc_media_list_retain
without a matchinglibvlc_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.
-
@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.