首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11中lambda的内存管理

C++11中lambda的内存管理
EN

Stack Overflow用户
提问于 2013-10-01 21:55:48
回答 1查看 1K关注 0票数 6

有人能描述一下为什么这段代码不能工作(在从调用返回之前,GCC4.7.3 seg-错误)吗?

代码语言:javascript
复制
#include <iostream>
#include <functional>
#include <memory>

using namespace std;

template<typename F>
auto memo(const F &x) -> std::function<decltype(x())()> {
    typedef decltype(x()) return_type;
    typedef std::function<return_type()> thunk_type;
    std::shared_ptr<thunk_type> thunk_ptr = std::make_shared<thunk_type>();

    *thunk_ptr = [thunk_ptr, &x]() {
        cerr << "First " << thunk_ptr.get() << endl;
        auto val = x();
        *thunk_ptr = [val]() { return val; };
        return (*thunk_ptr)();
    };

    return [thunk_ptr]() { return (*thunk_ptr)(); };
};

int foo() {
    cerr << "Hi" << endl;
    return 42;
}

int main() {
    auto x = memo(foo);
    cout << x() << endl ;
    cout << x() << endl ;
    cout << x() << endl ;
};

我最初的假设是:

  1. 每个std::function<T()>都是对某个表示闭包的对象的引用/shared_ptr。也就是说,拾取价值的生命时间受到它的限制。
  2. std::function<T()>对象有赋值操作符,它将放弃旧的闭包(结束生命时间选择的值),并获得新值的所有权。

P.S.这个问题是在我阅读question about lazy in C++11之后提出的

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-01 22:38:48

这是有问题的代码:

代码语言:javascript
复制
[thunk_ptr, &x]() {
    auto val = x();
    *thunk_ptr = [val]() { return val; };
    return (*thunk_ptr)(); // <--- references a non-existant local variable
}

问题是本地thunk_ptr是来自上下文的副本。也就是说,在赋值*thunk_ptr = ...中,thunk_ptr引用函数对象拥有的副本。然而,在赋值之后,函数对象就不再存在了。也就是说,在下一行中,thunk_ptr指的是刚刚销毁的对象。

有几种方法可以解决这个问题:

  1. 与其变得花哨,不如返回val。这里的问题是,return_type可能是一种引用类型,它会导致这种方法失败。
  2. 直接返回赋值的结果:在赋值之前,thunk_ptr仍然是活动的,在赋值之后,它仍然返回对std::function<...>()对象的引用: 返回(*thunk_ptr = val{返回val;})();
  3. 保存thunk_ptr的副本,并使用此副本调用return语句中的函数对象: std::shared_ptr tmp = thunk_ptr;*tmp = val {返回val;};返回(*tmp)();
  4. 保存对std::function的引用副本,并使用它而不是引用属于覆盖闭包的字段: auto &thunk = *thunk_ptr;thunk = val { return;};return ();
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19126671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档