"Dangling pointer deletion! Class: MouseCursor" when using ListBox


#1

Hey,
I started using a ListBox and ever since I am getting Assertion Errors and Warnings of a dangling pointer being deleted:

*** Dangling pointer deletion! Class: MouseCursor
JUCE Assertion failure in juce_LeakedObjectDetector.h:64

I am unsure right now where exactly this is coming from, but it has to do with the ListBox code somehow. Did anyone else bump into this problem and know what I missed to implement? I tried looking through the JUCE code but I am not sure why this dangling pointer is occurring:/

Thanks!


#2

Often when you get an assertion from the LeakObjectDetector, it can mean that the class which contains that object is being leaked/misused. So if ListBox contains a MouseCursor, you’ve probably just got a dangling pointer to the box itself and this is a symptom of that.


#3

In this case I think the problem is the opposite of a leak. The LeakDetector complains that an instance was already removed, when a RAII container tries to delete it (i.e. ScopedPointer or OwnedArray).

I.e. two containers own the same instance and both try to delete it, leaving one of them freeing unallocated memory.

But @jules’ hint applies here as well, it is not necessarily the MouseCurser, that is set somewhere, it is just the first one to complain. You can try hitting “Debug - continue” to hit the next assert, that might give additional clues…


#4

Thanks for the replies. I tried to look at the pointer to my ListBox, but I cannot find anything out of the ordinary. I am coding a plugin and the ListBox is being created in the PluginEditor. Perhaps some more details on what I’m doing:
– I have a private variable of type ListBox* in the header.
– In the PluginEditor constructor, I create a new instance of ListBox with the ‘new’ operator (empty constructor).
– I get my ListBoxModel pointer and set it as the model.
– Then I set the outline thickness to 1 and call ‘addAndMakeVisible’ with the ListBox pointer.
– Apart from that, I set the bounds of the ListBox in the ‘resized’ method of my PluginEditor.
– ListBoxModel merely implements ‘getNumRows’ and ‘paintListBoxItem’.

I noticed two more details to the problem (if that helps):
– First, the Assertion errors on the MouseCursor only start appearing after some time clicking around in the ListBox.
– Second, I also get the following output at the end of my program execution (amounts of leaked MouseCursor instances varies, other amounts double/triple/… with every opening on the plugin window, i.e. instantiating PluginEditor):

*** Leaked objects detected: 59 instance(s) of class MouseCursor
JUCE Assertion failure in juce_LeakedObjectDetector.h:88
*** Leaked objects detected: 10 instance(s) of class RowComponent
JUCE Assertion failure in juce_LeakedObjectDetector.h:88
*** Leaked objects detected: 2 instance(s) of class ListViewport
JUCE Assertion failure in juce_LeakedObjectDetector.h:88
*** Leaked objects detected: 2 instance(s) of class OwnedArray
JUCE Assertion failure in juce_LeakedObjectDetector.h:88
*** Leaked objects detected: 2 instance(s) of class ListBox
JUCE Assertion failure in juce_LeakedObjectDetector.h:88
*** Leaked objects detected: 4 instance(s) of class ScrollBar
JUCE Assertion failure in juce_LeakedObjectDetector.h:88
*** Leaked objects detected: 2 instance(s) of class Viewport
JUCE Assertion failure in juce_LeakedObjectDetector.h:88
*** Leaked objects detected: 22 instance(s) of class Component
JUCE Assertion failure in juce_LeakedObjectDetector.h:88
*** Leaked objects detected: 4 instance(s) of class AsyncUpdater
JUCE Assertion failure in juce_LeakedObjectDetector.h:88

The thing is, I never create any of these objects myself and my own ListBox should not be deleted/deallocated anywhere inside my own code, unless I’m mistaken. So I’m not sure how I end up with a dangling pointer to my ListBox :frowning:


#5

Literally ListBox* ? In that case best change it to
ScopedPointer<ListBox> myBox;

This way you can (i.e. must) omit the deletion, as it is taken care of. If not, you must check and delete the ListBox instance in your destructor (but this is old technique and should be avoided, it is to error prone).

Have a look at the ScopedPointer class…


#6

Ok, interesting, this removed all the other leaked objects, apart from the MouseCursor. (I think I tried using this pointer before, due to the assertion comment in juce_LeakedObjectDetector.h, but without much success either)

Yet, the flood of assertion errors for the dangling MouseCursor class still appear after some time of clicking around in the ListBox. In fact, when using an empty ListBoxModel, the pattern is more or less the following (I tried to dissect by commenting lines):

  • without ‘setAndMakeVisible’ nor ‘setBounds’: no assertion errors
  • with only ‘setBounds’ inside ‘resize’ commented out: +2 per opening/closing of PluginEditor window (i.e. 2 assertion errors on open, 4 on close, 6 on open again, 8 on close, etc…)
  • doing a full setup, i.e. including ‘setAndMakeVisible’ and ‘setBounds’: no constant increment, but always the same amount: 7 on first open, 14 on close, 25 on re-open, 28 on close, 64 on re-open, 42 on close, then some initial ones plus one on each mouse moving event.

Also, the ListBoxModel has the virtual method getMouseCursorForRow which I did not implement. The standard implementation returns an instance of NormalCursor::NormalCursor:

MouseCursor ListBoxModel::getMouseCursorForRow (int) { return MouseCursor::NormalCursor; }

I assume should not be the source for my problems, otherwise people would have problems with this in general. Apart from this, I am stumped as to where another MouseCursor might be created that is failing. Is there any chance I can find out where exactly this is failing?

Another oddity I forgot to mention is that my ListBoxModel resides in a Singleton, which I have placed in a dynamic library (so that plugins of different types can access the same singular ListBoxModel). Could this be the case for this happening?

Thanks!!


#7

So that’s good for a start.

Yes, it can’t be the problem, because it deals with the object on the stack rather than an instance on the heap (i.e. pointer). An object on the stack is removed automatically, when the scope ends, hence there can no leaks occur.

Singletons are always the last resort, so that worries me, but I can’t comment from here, if that is ok. Do you actually destroy the singleton anywhere?

Did you have a look at SharedResourcePointer?

Good luck…


#8

Hey, just wanted to reply I solved my problem with the frequent dangling MouseCursor assertion errors now by separating the actual model (an unordered_map) from the ListBoxModel. The unordered_map continues to reside inside the shared library, but each plugin instance reads from this unordered_map populating its own ListBoxModel. Hence all JUCE code resides only in the plugin instance and the shared library is pure C++ now.

Thanks for all your help!