Описание
Проблема происходит, когда лямбда-выражение получает объект ссылкой, и объект лямбда-выражения переживает полученный объект. Например, полученный объект является локальной переменной, но объект лямбда-выражения имеет намного больший осциллограф.
Риск
Если объект лямбда-выражения переживает один из полученных объектов своей ссылки, к полученному объекту можно получить доступ вне его осциллографа.
Например, рассмотрите этот функциональный createFunction
:
std::function<std::int32_t()> createFunction() {
std::int32_t localVar = 0;
return ([&localVar]() -> std::int32_t {
localVar = 1;
return localVar;
});
}
createFunction
возвращается лямбда-выражение возражают, что получает локальную переменную localVar
ссылкой. Осциллограф localVar
ограничивается createFunction
но возвращенный объект лямбда-выражения имеет намного больший осциллограф.
Эта ситуация может привести к попытке получить доступ к локальному объекту localVar
вне его осциллографа. Например, когда вы вызываете createFunction
и присвойте возвращенный объект лямбда-выражения другому объекту aFunction
:
auto aFunction = createFunction();
и затем вызовите новый объект
aFunction
:
std::int32_t someValue = aFunction();
полученная переменная
localVar
больше не находится в осциллографе. Поэтому значение, возвращенное от
aFunction
isundefined.
Фиксация
Если функция возвращает лямбда-выражение, чтобы не получать доступ к полученному объекту вне его осциллографа, убедитесь, что лямбда-выражение получает все объекты копией. Например, можно переписать createFunction
как:
std::function<std::int32_t()> createFunction() {
std::int32_t localVar = 0;
return ([localVar]() mutable -> std::int32_t {
localVar = 1;
return localVar;
});
}
Пример – указатель на Escape локальной переменной через лямбда-выражение
auto createAdder(int amountToAdd) {
int addThis = amountToAdd;
auto adder = [&] (int initialAmount) {
return (initialAmount + addThis);
};
return adder;
}
void func() {
auto AddByTwo = createAdder(2);
int res = AddByTwo(10);
}
В этом примере, createAdder
функция задает лямбда-выражение adder
это получает локальную переменную addThis
ссылкой. Осциллограф addThis
ограничивается createAdder
функция. Когда объект, возвращенный createAdder
называется, ссылка на переменную addThis
получен доступ вне его осциллографа. Когда получено доступ таким образом, значение addThis
isundefined.
Коррекция – получает локальные переменные копией в лямбда-выражении вместо ссылки
Если функция возвращает объект лямбда-выражения, постарайтесь не получать локальные переменные ссылкой в объекте lambda. Получите переменные копией вместо этого.
auto createAdder(int amountToAdd) {
int addThis = amountToAdd;
auto adder = [=] (int initialAmount) {
return (initialAmount + addThis);
};
return adder;
}
void func() {
auto AddByTwo = createAdder(2);
int res = AddByTwo(10);
}