简体   繁体   English

C ++ lambda函数访问写入违规

[英]C++ lambda function access write violation

I'm learning how to use C++ lambda functions along with <functional> 's function class. 我正在学习如何使用C ++ lambda函数和<functional>function类。 I am trying to solve this Code Golf as practice (challenge is Curry for Dinner) 我正在尝试解决这个Code Golf作为练习(挑战是咖喱晚餐)

I have this function: 我有这个功能:

// This creates a function that runs y a number of 
// times equal to x's return value.
function<void()> Curry(function<int()> x, function<void()> y)
{
    return [&]() {
        for (int i = 0; i < x(); i++)
        {
            y();
        }
    };
}

To test this I have this code in my main(): 为了测试这个我在main()中有这个代码:

auto x = [](){ return 8; };
auto y = [](){ cout << "test "; };
auto g = Curry(x, y);

This throws Access violation reading location 0xCCCCCCCC. 这将引发Access violation reading location 0xCCCCCCCC. in Functional.h. 在Functional.h中。

Yet when I copy-paste the lambda function from inside Curry() to inside my main like this: 然而,当我将lambda函数从Curry()内部复制粘贴到我的main中时,就像这样:

auto x = [](){ return 8; };
auto y = [](){ cout << "test "; };
auto g = [&]() {
    for (int i = 0; i < x(); i++)
    {
        y();
    }
};

I get the code running as expected. 我按预期运行代码。 Why does this happen? 为什么会这样?

You have a few problems. 你有一些问题。

Here: 这里:

  return [&]() {

you capture by reference . 通过参考捕获。 Any variables you capture has to have a lifetime that exceeds your own. 您捕获的任何变量都必须具有超出您自己的生命周期。 It means that running the lambda becomes undefined behavior after the variables you capture&use lifetime ends. 这意味着在捕获并使用生命周期结束的变量之后,运行lambda会变为未定义的行为。 As you are returning this lambda, and capturing local state, this seems likely to happen. 当你返回这个lambda并捕获本地状态时,这似乎很可能发生。 (Note I said variables -- due to a quirk in the standard, [&] captures variables not the data referred to by variables, so even capturing & function arguments by [&] is not safe. This may change in future revisions of the standard... There are neat optimizations that this particular set of rules allow in lambda implementations (reduce [&] lambdas to having 1 pointer worth of state(!)), but it also introduces the only case in C++ where you have a reference to a reference variable in effect...) (注意我说的变量 - 由于标准中的怪癖, [&]捕获变量而不是变量引用的数据,因此即使通过[&]捕获&函数参数也不安全。这可能会在将来的修订中发生变化。标准...这个特殊的规则集允许在lambda实现中进行简洁优化(将[&] lambdas减少为具有1个指针值的状态(!)),但它也引入了C ++中唯一具有引用的情况到一个有效的参考变量...)

Change it to 将其更改为

  return [=]() {

and capture by-value. 并按价值捕获。

Or even: 甚至:

  return [x,y]() {

to list your captures explicitly. 明确列出您的捕获。

When using a lambda which does not outlive the current scope, I use [&] . 当使用不超过当前范围的lambda时,我使用[&] Otherwise, I capture by value explicitly the stuff I am going to use, as lifetime is important in that case. 否则,我会通过值明确地捕获我要使用的东西,因为在这种情况下,生命周期很重要。

Next: 下一个:

    for (int i = 0; i < x(); i++)

you run x once for every loop iteration. 你为每个循环迭代运行一次x Seems silly! 好像很傻!

Instead: 代替:

    auto max = x();
    for (auto i = max; i > 0; --i)

which runs max times, and as it happens works if the return value of x was changed to unsigned int or whatever. 运行max次数,并且如果x的返回值更改为unsigned int或其他任何值,则会发生这种情况。

Or: 要么:

    int max = x();
    for (int i = 0; i < max; ++i)

which both runs x once, and behaves better if x returns -1 . 两者都运行x一次,如果x返回-1则表现更好。

Alternatively you can use the obscure operator --> : 或者你可以使用模糊的运算符-->

    int count = x();
    while( count --> 0 )

if you want to make your code unreadable. 如果你想让你的代码不可读。 ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM