Possible mem leak in DragAndDropContainer?


#1

I got this memory leak:

---------- Block 225003 at 0x0E63E4C8: 20 bytes ----------
  Call Stack:
    juce\src\containers\juce_array.h (1072): juce::Array<void *,juce::DummyCriticalSection>::operator new
    juce\src\gui\components\juce_component.cpp (2251): juce::Component::addMouseListener
    juce\src\gui\components\mouse\juce_draganddropcontainer.cpp (93): juce::DragImageComponent::DragImageComponent
    juce\src\gui\components\mouse\juce_draganddropcontainer.cpp (436): juce::DragAndDropContainer::startDragging
    components\mycomp.cpp (126): BypedIcon::mouseDrag == "DragAndDropContainer::findParentDragContainerFor(this)->startDragging(JUCE_T("1111111"), this);"
    juce\src\gui\components\juce_component.cpp (2814): juce::Component::internalMouseDrag
    juce\src\gui\components\windows\juce_componentpeer.cpp (258): juce::ComponentPeer::handleMouseDrag
    juce\src\native\windows\juce_win32_windowing.cpp (1344): juce::Win32ComponentPeer::doMouseMove
    juce\src\native\windows\juce_win32_windowing.cpp (1852): juce::Win32ComponentPeer::peerWindowProc
    juce\src\native\windows\juce_win32_windowing.cpp (1809): juce::Win32ComponentPeer::windowProc

So far, what I’ve understood, the mouse listener is a void * array so when you add a mouse listener, you must remove it specifically (deleting the voidarray will leak if any item is “new’d” before addition)
I don’t get where this happened after drag ended, am I missing something I forgot to do ?


#2

To leak the mouse listener list, you’d also have to leak the component that contains it. I’ve no idea how you’re managing to do that, but it doesn’t sound like a library bug.


#3

I don’t understand, probably I’m missing something obvious.
I’ve not deleted the dragged image component, but the container’s child component.
I don’t get any component leak in the report.

Just to be sure about object lifetime, when I call startDragging on the first drag container in the hierarchy, a new component is created (DragImageComponent), but my initial component still exists, right ?
Then when I get an itemDropped (or itemMoved as it’s where I delete the component), the drag image component is deleted, but the initial component still exists, right?
So, the parent of the initial component must still delete it, right ?
So if I delete the initial component any time after the startDragging is called, it should work, right ?


#4

The drag and drop code attaches a mouse listener to the component that the mouse is being dragged from, and uses it to track the mouse. If you delete that component while dragging, then obviously the drag will get aborted. I’ve no idea how it’d manage to leak though - when a component is deleted, it always deletes its mouse listener list. I can’t think of any way that the list could survive unless your build is a bit broken or something.


#5

I’ve rebuilt the application in release mode, and the leak doesn’t appear (or the leak detection code (VLD) is not working in release).

Anyway, as it’s one-shot 20 bytes (that’s the “new VoidArray(4)”), I’m not going to track this down.
I wonder if the VLD code interfer with juce’s “operator new” overloading, as it’s a place where realloc is used so this might over report stuff.

Ok, so if you’re sure there is no leak here by design, I’ll trust you.


#6

It must be something like that. I can’t imagine any way that it could possibly leak only that piece of data.