Leak detector and static variables


#1

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!


#2

For instance:

1. Use Singleton with DeletedAtShutdown inheritance.

2. Use SharedResourcePointer.

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


#3

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


#4

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!


#5


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.  


#6

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


#7

You're welcomed.

References for future readers: 

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

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


#8

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


#9

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?