Leak detector and static variables

Hi there,

I'm using the macro JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR in a class that I instantiate using a static, the class is destroyed properly but the leak detector is always telling me that there is a leak which it is not true. I would like to cover my back using the leak detector macro but I have this issue, how can I fix it?

Thanks!

For instance:

1. Use Singleton with DeletedAtShutdown inheritance.

2. Use SharedResourcePointer.

3. Create a dummy object to reverse the order of the static initializers.

And use function-scoped statics, not file-scoped statics.

1. As I'm building a library with no UI I can not use DeletedAtShutdown

2. It is not very clear to me how to use SharedResourcePointer with static fields, can anybody write an example?

3.  How can I create a dummy object to reverse the order of the static initializers? any example?

Thanks!


AFAIK.


The leak detector of a class FOO is based on a local static variable and is built at the first instantiation of a FOO object. So according to C++ standard every static object constructed before will be released after (in reverse order). That's why you get false-positives. When the leak detector is destroyed (as Foo objects could still be owned by those oldest static objects) leaks are reported. 

Note that "constructed" means totally constructed. If a static A calls a local static B in its constructor, B will be considered constructed before A. So B will be released after A. Note that "local static" means "function static" and "non-local" static means "global static". 

I'm not english speaking native. So please correct me if something is wrong.

Various approaches could be used to turn off LEAK_DETECTOR hell, but it really depends on situations. 

0. Do NOT use LEAK_DETECTOR in that case.

1. You could use an Initialize/Shutdown instead (as JUCE does) to explicitly manage order of construction.

2. SharedResourcePointer example in the documentation isn't good enough?

3. Example:

   - Static class FOO is constructed.

   - Static class BAR is constructed (with LEAK_DETECTOR).

   - A BAR instance is added to (owned by) the FOO container. 

   - Shutdown.

   - BAR's LEAK_DETECTOR destructor is called : Warning! There's still a BAR instance in FOO!

   ...

   Solution: Instantiate a dummy BAR before FOO. It can be in the FOO constructor ;-)

class Foo {
    public:
        Foo( ) { Bar("Dummy"); }
};

class Bar {
    public:
        Bar(const String& hello) { DBG(hello); }

    private:
        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Bar)
};

static Foo container;

   ...

   Now:

   - Static class FOO constructor is called.

   - The static BAR's LEAK_DETECTOR is constructed.

   - Static class FOO is constructed.

   - A BAR instance is added to (owned by) the FOO container.

   - Shutdown.

   - FOO destructor is called.

   - BAR's LEAK_DETECTOR destructor is called.  

1 Like

Thanks, now is clear! I fixed the issue with the leak detector :)

You're welcomed.

References for future readers: 

- http://stackoverflow.com/a/3737070

- http://isocpp.org/files/papers/N3690.pdf

1 Like

Hi

though i understood the principle of the solution, I could not figure out how to implement this, since I am using here JUCE classes, that I am not willing to mofify.

To be clearer, here is part of my code:

Let’s say MyClass is a user defined class:

class MyClass
{
// some code

    static AudioDeviceManager& getDeviceManager()
    {
        static AudioDeviceManager deviceManager;

        return deviceManager;
    }
};

How can I use the dummy thing in my case?

Thank you
Nathaniel

The dummy trick above is not relevant here (anyway IMHO it is never an elegant solution).
I’m not used with the AudioDeviceManager class.
In your code the AudioDeviceManager is locally static ;
I suppose thus that its leak detector is constructed last.
Is there any static class that owns an instance of it and that is constructed before?

Have spent an embarrassingly long time debugging a detected leak to find it’s just this - the object with the leak detector was being constructed after the static container it was added to.

No fix for this on the JUCE side AFAIK, but it would be nice if the needlessly-passive-aggressive comment above the assertion in juce_LeakedObjectDetector.h could be updated to mention something about this edge case with statics:

Super simple repro if it’s at all helpful:

struct NoLeak
{
    NoLeak() { DBG("Constructed"); }
    ~NoLeak() { DBG("Destructed"); }

    JUCE_LEAK_DETECTOR(NoLeak)
};

int main()
{
    static std::unique_ptr<NoLeak> noLeak;
    noLeak = std::make_unique<NoLeak>();

    return 0;
}
JUCE v7.0.5
Constructed
*** Leaked objects detected: 1 instance(s) of class NoLeak
JUCE Assertion failure in juce_LeakedObjectDetector.h:92
Destructed

If you don’t want a leak detected, just don’t add the leak detector.

A better way is to use a singleton like mentioned before. And to have your class properly cleaned up, you can have a look at the DeletedAtShutdown class.

1 Like

Neither of those are an option for my case since the class in question is a fairly generic data structure of which I’d expect to have many instances in an applicaiton, and it inherits from a JUCE class that itself has a leak detector, so I’d just get less helpful warnings instead.