从函数返回共享指针与在 Lambda 中捕获共享指针

Return a shared pointer from a function vs Capturing a shared pointer in a Lambda

提问人:Vero 提问时间:11/13/2022 最后编辑:pm100Vero 更新时间:11/17/2022 访问量:259

问:

我正在 a 中构造一个共享指针,并将其作为 lambda 的捕获。function_1

我认为这是一个问题,你能确认这是否安全还是我是对的,我不应该这样做?

#include <memory>
#include <future>
#include <iostream>
#include <vector>

using Op = std::function<double(std::size_t)>;
struct A
{
    std::shared_ptr<const std::vector<double>> function_1() const
    {
        const std::vector<double> v = {1.0, 2.0};
        auto pVec = std::make_shared<const std::vector<double>>(v);
        return pVec;
    };
};

struct B
{
    B() { m_a = A(); };
    
    void populate_op(Op& op) const
    {
        std::shared_ptr<const std::vector<double>> pVec = m_a.function_1();
        op = [pVec](const std::size_t index) -> double
        {
            return pVec->at(index);
        };
    }
    
    void run()
    {
        m_futures.resize(2u);
        Op op0;
        populate_op(op0);
        m_futures[0u] = std::async(std::launch::async, op0, 0u);
        
        Op op1;
        populate_op(op1);
        m_futures[1u] = std::async(std::launch::async, op1, 1u);
        
        const double res0 = m_futures[0u].get();
        const double res1 = m_futures[1u].get();
        
        std::cout << res0 + res1 << std::endl;
        //clean futures
    }
    
private:
    A m_a;
    mutable std::vector<std::future<double>> m_futures;
};

int main() {
    B b;
    b.run();
    return 0;
}

它不会被破坏,因为它是一个局部变量,我最终会得到一个移动的共享指针,指向一个被破坏的对象,从而在 lambda 中捕获后者?v

C++ Lambda 智能指针 rvalue dangling-pointer

评论

0赞 Vero 11/13/2022
共享指针可能正在复制对象,我应该没有问题?如果向量本身是指向对象/实例的指针,而不仅仅是双精度值,该怎么办?谢谢!!!

答:

1赞 newacct 11/17/2022 #1

shared_ptr是指向动态分配的存储的智能指针,该存储包含共享的值。 分配该存储并通过将传递的参数传递给该类型的构造函数来构造值。在这种情况下,由于您是通过传递 来构造 的,因此它调用 的复制构造函数。共享存储中的和您传递的是完全独立的对象;只是一个是通过复制另一个来构建的。make_sharedvectorvectorvectorvectorvector

所以是的,当范围结束时会被破坏。这与动态分配的共享存储中的单独存储无关。当引用计数确定不再有 指向该共享存储时,该存储将被销毁(并释放内存)。vvvectorvectorshared_ptr