View Issue Details

IDProjectCategoryView StatusLast Update
0002370NoesisGUIC++ SDKpublic2025-05-23 17:59
Reporternikobarli Assigned Tojsantos  
PrioritynormalSeveritymajor 
Status assignedResolutionopen 
Product Version3.1.3 
Target Version3.1.7 
Summary0002370: Crash when using lambda expression for delegate
Description

We experience crashes when using lambda expression for RoutedEvent handlers. The crash occurs under the following conditions:

  1. The lambda expression contains captured variables
  2. Inside the handler there's a code to add another event handler (using += etc)
  3. Accessing a captured variable after the previous addition of event handler

Sample code:

auto p = std::make_shared<Data>();
elem->Loaded += [p](auto sender, const auto& ea) {
   auto elem = DynamicCast<FrameworkElement*>(sender);
   elem->MouseRightButtonUp += ... // Add event handler
   p->DoSomething();  // Crash here when accessing p (its value becomes invalid)
}

It seems that the cause is the use of HashMap to store the element's event handlers. The current HashMap implementation will reallocate the handlers at some point when resizing is necessary, and the executing handler will get destroyed before finishing its execution (the lambda member variables are also destroyed).

PlatformWindows

Activities

jsantos

jsantos

2022-07-05 16:45

manager   ~0008009

Problem is, our hashmap is not using stable pointers... So, probably we need to change the hashmap to contain pointer to Delegates instead of Delegates.

I want to analyze this carefully, because the change is going to increase the number of allocations.

sfernandez

sfernandez

2022-07-05 16:46

manager   ~0008010

Last edited: 2025-05-23 17:59

Reproduced with the following test:

struct Data
{
    int i;
    Data(int i_): i(i_) { }
    int Foo(int x) { return i + x; }
};

HashMap<int, Delegate<void(int)>> map;
map.Insert(0, [](int) {});

{
    std::shared_ptr<Data> data = std::make_shared<Data>(5);
    Delegate<void(int)> d = [data, &map](int i)
    {
        map.Insert(2, [](int) {});
        int r = data->Foo(i);
        printf("%d", r);
    };

    map.Insert(1, d);
}

HashMap<int, Delegate<void(int)>>::Iterator it = map.Find(1);
it->value(7);

Issue History

Date Modified Username Field Change
2022-07-02 07:35 satorp New Issue
2022-07-05 10:53 sfernandez Assigned To => sfernandez
2022-07-05 10:53 sfernandez Status new => assigned
2022-07-05 10:53 sfernandez Target Version => 3.1.6
2022-07-05 11:14 sfernandez Assigned To sfernandez => jsantos
2022-07-05 16:45 jsantos Note Added: 0008009
2022-07-05 16:46 sfernandez Note Added: 0008010
2022-11-07 17:13 sfernandez Target Version 3.1.6 => 3.1.7
2024-06-14 20:18 jsantos Reporter satorp => nikobarli
2025-05-23 17:58 jsantos Description Updated
2025-05-23 17:59 jsantos Note Edited: 0008010