Unexplained Memory Leak in Condition Variable

I am on TDM-GCC 4.8.1, Windows 8, x64.

Having only a mutex and a condition variable without using them does not leak.

What am I doing wrong here? Mem usage goes up to 100MB and over, I have to close the app before it consumes all my memory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for (int i = 0;; ++i)
    {
        std::condition_variable cnd_var;
        std::mutex mx;
        bool notif = true;

        std::unique_lock<std::mutex> lock(mx);
        cnd_var.wait(lock, [&notif]() -> bool {return notif;});
        notif = false;

        if (i == 99)
        {
            i = 0;
            std::cout << "still running\n" << rand();
        }
    }



Edit:

Trying to use the official sample here: http://en.cppreference.com/w/cpp/thread/condition_variable

I changed it to allow iterations, and it still leaks at a steady rate.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
for (int i = 0;; ++i)
{
    std::mutex m;
    std::condition_variable cv;
    std::string data;
    bool ready = false;
    bool processed = false;

    auto worker_thread = [&]() -> void
    {
        // Wait until main() sends data
        {
            std::unique_lock<std::mutex> lk(m);
            cv.wait(lk, [&]{return ready;});
        }

        std::cout << "Worker thread is processing data\n";
        data += " after processing";

        // Send data back to main()
        {
            std::lock_guard<std::mutex> lk(m);
            processed = true;
            std::cout << "Worker thread signals data processing completed\n";
        }
        cv.notify_one();
    };


    {
        std::thread worker(worker_thread);

        data = "Example data";
        // send data to the worker thread
        {
            std::lock_guard<std::mutex> lk(m);
            ready = true;
            std::cout << "main() signals data ready for processing\n";
        }
        cv.notify_one();

        // wait for the worker
        {
            std::unique_lock<std::mutex> lk(m);
            cv.wait(lk, [&]{return processed;});
        }
        std::cout << "Back in main(), data = " << data << '\n';

        worker.join();
    }
}
Last edited on
Looks like it is a bug in MinGW http://sourceforge.net/p/tdm-gcc/bugs/203/
Looking at the description, this fixes it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::mutex mx;
for (int i = 0;; ++i)
    {
        std::condition_variable cnd_var;
        bool notif = true;

        std::unique_lock<std::mutex> lock(mx);
        cnd_var.wait(lock, [&notif]() -> bool {return notif;});
        notif = false;

        if (i == 99)
        {
            i = 0;
            std::cout << "still running\n" << rand();
        }
    }

You just need std::mutex to be in an earlier scope.

(Personally tested and it's not going over 2mb of ram where your example also gave me 100mb+ of used ram)
Last edited on
Interesting, thanks.

I asked a good companion of mine to test my code and he had no leaks whatsoever (Visual C++). Too bad this bug is inside the library implementation and there's pretty much nothing I can do about it but wait for an update or change library implementation.
Well, that's to be expected, it's specifically a winpthreads bug as stated in the bug report, VC++ doesn't use winpthreads.

We'll just need a bugfix/patch.
Topic archived. No new replies allowed.