ApplicationProperties with leaking PropertiesFile

In a audio plugin I use a Preferences Class that looks like this:

class Preferences {
    
public:
    Preferences ()
    {
        PropertiesFile::Options options;
        
        options.applicationName = ProjectInfo::projectName;
        options.osxLibrarySubFolder = "Application Support";
        options.folderName = ProjectInfo::companyName;
        options.filenameSuffix = ".settings";

        prefs.setStorageParameters (options);
    }

    String getProperty (String key)
    {
        PropertiesFile* prefFile = prefs.getUserSettings();
        jassert (prefFile->isValidFile());
        
        String value = prefFile->getValue(key);
        return value;
    }
  
    void setProperty (String key, String value)
    {
        PropertiesFile* prefFile = prefs.getUserSettings();
        jassert (prefFile->isValidFile());
    
        prefFile->setValue(key, value);
        prefFile->saveIfNeeded();
    }

    ApplicationProperties prefs;
};

This class is used in 3 different Components like this:

Preferences preferences;

String myPrefValue (preferences. getProperty(myPrefKey));
...
preferences.setProperty(myKey, myValue);

The plugins works fine until I close the hosting app, then I get the error:

*** Leaked objects detected: 2 instance(s) of class PropertiesFile

The Leaks only occure in the AudioUnit, but not in the VST3.

I do not quite understand, what’s going wrong here.
My search here in the forum just leads me to some very old topics…

Can anyone help to point me in the right direction?

Thanks!

The code looks correct to me. The getUserSettings() returns indeed an unowned object, so it is fine not to delete it or putting it into a unique_ptr.

First thing to check is, if by any chance the whole Preferences class leaks somewhere?

  • First: add the JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Preferences) macro at the end of your class
  • Second: When it happens again, hit continue. Only then you will see the class that contains the Preferences. When the parent leaks, this leaks as well, but it is detected from inside to the outside.
  • Third: You don’t use any static variables by chance? They also leak if not cleaned up properly. Better don’t use statics.

Thanks for your help, @daniel !

I was able to follow it down to one OtherClass that has a Preferences attribute. And the instance of this OtherClass is created with otherclass = new OtherClass() and is destroyed with a delete otherclass call.

And in the LeakCounter class, I found this comment:

If you’re leaking, it’s probably because you’re using old-fashioned, non-RAII techniques for
your object management. Tut, tut. Always, always use std::unique_ptrs, OwnedArrays,
ReferenceCountedObjects, etc, and avoid the ‘delete’ operator at all costs!

So I think, this is the reason for the reference counting mismatch.

When I avoid new and delete and create my instances like this:

PluginProcessor ()
: otherclass()
{
...
}

the leaks are gone!
:rocket:

1 Like