Having troubles with smart pointers and vectors, constant crashing

136 Views Asked by At

So im trying to build a merkle tree from a vector of strings, first convert all the strings to the MerkleNodes and then form their parents, building the tree upside down. But it seems to be an issue when i push all the nodes to the vector in the first FOR loop, because i cant access to them. I ve debug it and that seems to be the problem altough i dont know what else i can do, actually I first try with raw pointers but get the same issue.

  inline std::shared_ptr<MerkleNode> AddLeaf(const std::string &vright, const std::string &vleft) {
     std::shared_ptr<merkle::MerkleNode> right (new MerkleNode (vright));
     std::shared_ptr<merkle::MerkleNode> left (new MerkleNode (vleft));
     return std::make_shared<merkle::MerkleNode>(std::move(left), std::move(right));
 }

 std::shared_ptr<merkle::MerkleNode> Build(const std::vector<std::string> &values) {
     std::vector< std::shared_ptr<merkle::MerkleNode> > nodes(values.size());

     for (const auto &value: values) {
         nodes.push_back(std::make_shared<merkle::MerkleNode>(value));
     }
// I verify that the values are correct and that inmediatly after the push_back i can access to the nodes. 
//But in the second FOR loop with iterators i get ERROR -1073741819 (0xC0000005) when accessing the elemnts.
     std::vector< std::shared_ptr<merkle::MerkleNode> >::iterator it;
     while (nodes.size() > 1) {
         if (nodes.size() % 2 != 0) nodes.push_back(std::move(nodes.back()));
         std::vector<std::shared_ptr<merkle::MerkleNode> > new_nodes;

         for (it = nodes.begin(); it != nodes.end(); it += 2) {
             //std::shared_ptr<merkle::MerkleNode> h(it->get());

             auto temp = std::move(AddLeaf((*it)->hash(),(*(it+1))->hash()));
             new_nodes.push_back(std::move(temp));
         }
         //nodes = new_nodes;

     }
     return std::move(std::shared_ptr<MerkleNode>(nodes[0].get()));
 }
2

There are 2 best solutions below

1
Coding_in_india On

Just use RAW pointers and FOR EACH, iterators and smart pointers just too much thinking...

0
Andrei M. On

Treat shared_ptr as a value type i.e. pass the pointer itself by copy, in order to propagate ownership, which is what this smart pointer is intended for.

Also, move shouldn't be used when returning because it interferes with compiler optimizations. The compiler knows that the return item should be moved into a new scope (return value optimization).

For more details, see this ISO CPP guideline about move: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es56-write-stdmove-only-when-you-need-to-explicitly-move-an-object-to-another-scope

Speaking for the code sample, you would probably benefit from moving large strings into new owners, if they're not used elsewhere after moving.