1

I am constructing a shared pointer in a function_1 and giving it as a capture to a lambda.

I think this is an issue, could you please confirm if this safe or I am right and I shoudn't be doing this?

#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;
}

Wont the v be destructed as it's a local variable and I will end up with a moved shared pointer pointing to a destructed object and hence capturing the latter in the lambda?

pm100
  • 48,078
  • 23
  • 82
  • 145
Vero
  • 313
  • 2
  • 9
  • Likely the shared pointer is copying the object and I shouldn't have issues? What if the vector itself is of pointers to objects/instances instead of just of doubles? Thank you!!! – Vero Nov 13 '22 at 01:41

1 Answers1

1

shared_ptr is a smart pointer to dynamically-allocated storage holding the value that is shared. make_shared allocates that storage and constructs the value by passing the passed arguments to the constructor of the type. In this case, since you are constructing a vector by passing a vector, it calls vector's copy constructor. The vector in the shared storage and the vector that you passed are completely separate objects; it's just that one was constructed by copying the other.

So yes, v will be destructed when v's scope ends. This has nothing to do with the separate vector in the shared storage that was dynamically allocated. That vector will be destructed (and the memory freed) when the reference counting determines that there are no more shared_ptr's pointing to that shared storage.

newacct
  • 119,665
  • 29
  • 163
  • 224