Memory leaks with lambda expressions RRS feed

  • Question

  • Hello, I have the following code where I'm capturing a variable (test) which is an instance to a ref class.

    ThreadPool::RunAsync(ref new WorkItemHandler([test](Windows::Foundation::IAsyncAction^ operation) { ... }))->Start();

    C++ variables captured in this way are copied. I assume the instances of ref classes are just retained (using AddRef internally). The problem is that the instance isn't disposed when the lambda expression is destroyed. My understanding is that the instance of WorkItemHandler should be destroyed when the async operation is finished along with the lambda expression which should release all variables that are not captured by reference.

    Is this a bug in the preview version of the compiler or am I doing something wrong?

    • Edited by Atamiri Monday, October 31, 2011 10:17 PM
    Friday, October 28, 2011 4:56 PM


All replies

  • Your expectations are correct, but we can't reproduce the behavior you are seeing with just the minimal snippet above. Can you provide a complete, minimal repro? What are you observing that leads you to believe there's a missing release call? I ask because it's also possible that some other component wiring is broken, instead.




    Ben Kuhn

    Monday, October 31, 2011 9:13 PM
  • Hi Ben, thank you for looking at my problem. In the code below the destructor of Test isn't called. It's called if I use [&] instead of [=].


    ref class Test {
    	~Test() { OutputDebugStringW(L"Disposed\n"); }
    	void Dummy() { OutputDebugStringW(L"Dummy\n"); }
    delegate void MyDelegate();
    int main(array<Platform::String^>^) {
    		auto test = ref new Test();
    		auto lmbd = [=](){ test->Dummy(); };
    		auto dlgt = ref new MyDelegate(lmbd);
    Monday, October 31, 2011 10:25 PM
  • I can repro the OP's problem using similar code. The introduction of a lambda seems to prevent the destructor from being called. (not a problem when you capture by &)

    Wednesday, November 2, 2011 2:51 PM
  • When you capture by value there is one Release() missing. I wonder if this may be due to a bug in attempting to optimize away a AddRef/Release when it's determined to not be required.
    Wednesday, November 2, 2011 3:08 PM
  • Possibly. I've sent this over to the compiler team to have someone take a look. I'll post back here as soon as I get a response.




    Ben Kuhn

    Wednesday, November 2, 2011 4:59 PM
  • @Atamiri

    As there is some investigation required for this, would you mind filing a bug for this issue?


    Bug filing form for VS11 is here:

    Thursday, November 3, 2011 6:55 PM
  • Hi David, OK, I'll file a bug.

    Thank you

    Thursday, November 3, 2011 10:57 PM
  • Hi David, OK, I'll file a bug.

    Thank you

    Please post the link here when you do so, so others can vote it up.
    Friday, November 4, 2011 2:55 PM
  • Following up, I couldn't find a bug yet so I created one located here:


    Wednesday, November 16, 2011 7:48 PM