相关疑难解决方法(0)

C++ 11 lambda实现和内存模型

我想了解一些关于如何正确思考C++ 11闭包以及std::function如何实现它们以及如何处理内存的信息.

虽然我不相信过早优化,但我确实习惯在编写新代码时仔细考虑我的选择对性能的影响.我还进行了大量的实时编程,例如微控制器和音频系统,其中要避免非确定性的存储器分配/解除分配暂停.

因此,我想更好地了解何时使用或不使用C++ lambdas.

我目前的理解是没有捕获闭包的lambda就像一个C回调.但是,当通过值或引用捕获环境时,将在堆栈上创建匿名对象.当必须从函数返回值闭包时,将其包装进去std::function.在这种情况下闭包内存会发生什么?它是从堆栈复制到堆?它是否在被释放时std::function被释放,即它是否被引用计数为std::shared_ptr

我想在实时系统中我可以建立一个lambda函数链,将B作为一个连续参数传递给A,以便A->B创建一个处理管道.在这种情况下,A和B闭包将被分配一次.虽然我不确定这些是否会在堆栈或堆上分配.然而,一般来说,这在实时系统中使用似乎是安全的.另一方面,如果B构造一些它返回的lambda函数C,那么C的内存将被重复分配和释放,这对于实时使用是不可接受的.

在伪代码中,一个DSP循环,我认为这将是实时安全的.我想执行处理块A然后执行B,其中A调用它的参数.这两个函数都返回std::function对象,因此f它将是一个std::function对象,其环境存储在堆上:

auto f = A(B);  // A returns a function which calls B
                // Memory for the function returned by A is on the heap?
                // Note that A and B may maintain a state
                // via mutable value-closure!
for (t=0; t<1000; t++) {
    y = f(t)
}
Run Code Online (Sandbox Code Playgroud)

我认为在实时代码中使用它可能很糟糕:

for (t=0; t<1000; t++) {
    y = A(B)(t); …
Run Code Online (Sandbox Code Playgroud)

c++ memory lambda c++11

88
推荐指数
2
解决办法
2万
查看次数

在C++ 11 lambda语法中,堆分配闭包?

C++ 11 lambdas很棒!

但缺少一件事,就是如何安全地处理可变数据.

以下将在第一次计数后给出错误计数:

#include <cstdio>
#include <functional>
#include <memory>

std::function<int(void)> f1()
{
    int k = 121;
    return std::function<int(void)>([&]{return k++;});
}

int main()
{
    int j = 50;
    auto g = f1();
    printf("%d\n", g());
    printf("%d\n", g());
    printf("%d\n", g());
    printf("%d\n", g());
}
Run Code Online (Sandbox Code Playgroud)

给,

$ g++-4.5 -std=c++0x -o test test.cpp && ./test
121
8365280
8365280
8365280
Run Code Online (Sandbox Code Playgroud)

原因是在f1()返回后,k超出范围但仍在堆栈上.所以第一次g()执行k是好的,但在那之后堆栈被破坏并k失去其价值.

因此,我在C++ 11中设法安全地返回闭包的唯一方法是在堆上显式分配闭合变量:

std::function<int(void)> f2()
{
    int k = 121;
    std::shared_ptr<int> o = std::shared_ptr<int>(new int(k)); …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11

21
推荐指数
1
解决办法
6922
查看次数

标签 统计

c++ ×2

c++11 ×2

lambda ×2

memory ×1