Hi guys, We've been fixing a few resource leaks recently, and I suspect it would pay to remind people of the documentation on VclPtr:
https://gerrit.libreoffice.org/gitweb?p=core.git;a=blob;f=vcl/README.lifecycle;h=6ef91ccfce51d4b5daeb7d03527f471233ae71ab;hb=HEAD I guess I should update that now the transitional stuff is obsolete. But here is the punch-line: **** please call disposeAndClear() **** or, use: ScopedVclPtrInstance<Foo> aFoo(...); which will do it for you when your variable goes out of scope. * Wait but why ? VclPtr is very much like a shared_ptr<> or any other such smart-reference counting thing (it differs for only rather boring reasons). What is different is VCL; so take for example this: { VclPtr<VirtualDevice> xDev(VirtualDevice::Create()); // VclPtrInstance<VirtualDevice> xDev; - its synonym. ... do something temporary with xDev ... } // exit scope. It looks safe, what could go wrong ? the smart pointer will go out of scope, and xDev will be deleted - right ? it is not easy to see anyone else taking a reference to xDev ... so ... Beware - the reason is that VCL is infested with scads of lists of internal smart pointers all to each other: include/vcl/virdev.hxx class VCL_DLLPUBLIC VirtualDevice : public OutputDevice { private: VclPtr<VirtualDevice> mpPrev; VclPtr<VirtualDevice> mpNext; Oh dear - each VirtualDevice is part of a manually maintained linked list of safe but problematic VirtualDevices. And to add insult to injury we have: include/vcl/outdev.hxx class VCL_DLLPUBLIC OutputDevice : public virtual VclReferenceBase { private: mutable VclPtr<OutputDevice> mpPrevGraphics; ... mutable VclPtr<OutputDevice> mpNextGraphics; ... So - each VirtualDevice is part of two doubly linked lists. Windows (derived from OutputDevice) takes part in many more hierarchical structures too ... * Summary: Calling dispose is a good plan ! =) This releases all of these references, lists etc. and also frees any underlying resources - leaving only an empty shell of an object around until the last object is released. So: { // correct VclPtrInstance<VirtualDevice> xDev; ... do something temporary with xDev ... xDev.disposeAndClear() } Or better: { // correct ScopedVclPtrInstance<VirtualDevice> xDev; ... } // auto-disposes outside the scope. * Why bother with a smart pointer then ? So - since we have to replace what would be a 'delete' with a disposeAndClear() anyway - why bother in the first instance ? the answer here is that LibreOffice is quite good at getting deep call stacks around even emission, referencing Windows and being sure that the Window is still alive, and has a valid handle (so we can reliably check it is alive) as we return through those makes life lots cleaner and easier. The nice thing about vclptr is that you can call disposeAndClear several times from different paths in different orders, and you can be sure that if the pointer is not NULL it is always valid. I hope that helps someone - very happy to help if anyone is in doubt etc. ATB, Michael. -- michael.me...@collabora.com <><, Pseudo Engineer, itinerant idiot _______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice