Static image memory leak

It seems I just can’t figure this one on my own.

The following code generates a memory leak, but why?

class pngHandler
{

public:    

     static pngHandler& Get()
     {
         static pngHandler instance;
         return instance;
     }
 
	  void InitGUI()  { 
      knobImage = juce::PNGImageFormat::loadFrom(juce::File("some_file.png"));	
     }

private:
	juce::Image knobImage;	
	pngHandler() {}

};

In MainComponent’s constructor:

pngHandler::Get().InitGUI();

Once the main GUI window is terminated, an assertion is raised saying that a SoftwarePixelData object is leaking.

It’s because of the order the destructors of the objects are run when shutting down. The Juce memory leak detector is destroyed first and it notices the Image hasn’t yet been destroyed and triggers the memory leak warning.

Why do you need to have the Image as a static object?

1 Like

pngHandler does a lot of stuff and handles every component in the app. I just want to be able to access it from any class so I made it a singleton, where I can call it from anywhere with just one line. Is it bad to have a static image? (This particular image should also be passed to multiple knobs to serve as a background).

It’s bad to have static variables to begin with, you are going to end up having those Juce memory leak warnings for other Juce objects too, not just Images.

Juce does however have some helper utilities for dealing with singletons like the JUCE_DECLARE_SINGLETON macro. I have not myself used that because I want to keep my code compatible for use in plugins.

1 Like

Noted, thanks.

That’s not a good reason to have a singleton. All you have to do is provide a getter() in the owner of the pngHandler to get a reference to that object, and use that to access the pngHandler object.

1 Like

The essence of pngHanlder is that there should be only one of it to handle the app’s boiler plate stuff, and every component from the top level to the last child should be able to access it directly in order to feed some data into it. Considering this, isn’t a singleton a right choice?

No. Why? Make it a member of the editor itself, and let the components ask the editor for a reference to it. That gives you a single instance, because there is only one editor.

Noting that you say App rather than plugin, and assuming you use the projucer app/GUI template you could create your pngHandler as a member of the your class that extends juce::JUCEApplication and pass a ref into the MainWindow and so on.

My apps and more complex plugins all have a ‘context’ class that is effectively a bag of such common systems and it gets passed by reference around the UI mostly to minimise the amount of constructor params whilst avoiding global statics but also to keep the ‘business logic’ separate from the more transient UI.

HTH,
Dave

1 Like

And, to follow on what @dave-elton says. depending on the data you want to store and access, I use a ValueTree based system, where I pass in PersistantProperties and RuntimeProperties ValueTrees to all Components, which can then use a set of helper classes/wrappers to find and use specific data from those ValueTrees

In case you missed it, there is a good solution for image assets, the ImageCache. Images are loaded only once, and the pixel data is already shared, so no copying and no extra loading takes place. And the ImageCache has static methods to access the images, no need to pass around pointers or references.