#method call forces pointers deletion

47 messages · Page 1 of 1 (latest)

spark belfryBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

rancid pilot
#

If the vector reallocates because the current allocation is too small for the new element, then it must destroy the D objects in the old allocation

sinful kayak
#

What can I do then?

#

it's a reference pass

#

it shouldn't reallocate no?

#

I just added a value?

#

it reallocates the entire array

#

?

rancid pilot
#

std::vector<D> stores D elements contiguously in memory. v.insert(it, data) adds a new one before it and that new D is a copy of data.

#

If there is no space left in the contiguous memory that the vector allocated for the elements, then it needs to move-construct all the D already in it to a new allocation.

#

And then it destroys all the D elements in the old allocation.

sinful kayak
#

That's terrible though

#

When that happens

#

look at my stacktrace

#
Abandon (core dumped)
#

Like what I'm doing is basically this

#

I have a WeightedBinaryTree

rancid pilot
#

That is probably an issue with how your class is designed. Does it follow the rule-of-3 or rule-of-5?

sinful kayak
#

It has a bunch of methods:
leaf meaning the node is a leaf and complex if the node has a left and right node

#
    static WeightedBinaryTree<W,D> leaf(W weight, D data){
                return WeightedBinaryTree<W,D>(weight,data);
            }

            static WeightedBinaryTree<W, D> complex(WeightedBinaryTree<W, D>* left,WeightedBinaryTree<W, D>* right) {
                W weight = left->get_weight() + right->get_weight();
                return WeightedBinaryTree<W,D>(weight, std::make_pair(left, right));
            }
            bool is_leaf() const {
                return std::holds_alternative<D>(m_content);
            }
            
            bool is_complex() const {
                return std::holds_alternative<std::pair<WeightedBinaryTree<W,D>*,WeightedBinaryTree<W,D>*>>(m_content);
            }
            
            W const get_weight() const {
                return this->m_weight;
            }

            D const& get_data() const {
                if (this->is_leaf())
                    return std::get<D>(m_content);
                throw std::runtime_error("Tentative d'accès aux données d'un noeud non-terminal");
            }

#

Those are the methods kind off

rancid pilot
#

The important part is that it has copy (and move) constructor and assignment and that they leave the object in a state that can be safely destructed. That's the rule of-3/5.

sinful kayak
#

So I need to make an std::move on my assignments?

#

cuz I've been struggling on that yesterday

#

and well it's a pain

#

basically The goal is

#

I'd have a hashmap

rancid pilot
#

No, your class WeightedBinaryTree should have a copy constructor and a copy assignment operator that make sense, so that calling the destructor on a copy will always be safe.

sinful kayak
#

sthing like this

rancid pilot
#

Forget move for a moment, that is only an optimization for later.

sinful kayak
#

{'a': 4,'b': 6,'c':5}
Where the keys are the data of the tree and the value is basically the weight of the node

#

I would create a vector of leafs

#

in the beginning

rancid pilot
#

There is already a hash map in the standard library, it is called std::unordered_map.

sinful kayak
#

meaning that I'll have [leaf('b',6),leaf('c',5),leaf('b',4)]

sinful kayak
#

that's what I used

#

but

#

Then I want to regroup all leafs into 1 big tree

#

and here the problem happens

#
 std::vector<utils::WeightedBinaryTree<std::size_t, D>> trees;
        std::cout << "HERE" << std::endl;
        for (const auto& [data, freq] : frequency_map) {
            utils::insert_in_isorted(trees, utils::WeightedBinaryTree<std::size_t, D>::leaf(freq, data));
        }
        std::cout << trees.size() << std::endl;
        for (int i = 0;i < trees.size() ; i++){
                    std::cout << trees[i].get_weight() << " ";
        } 

        while (trees.size() > 1) {
        
            auto left = utils::WeightedBinaryTree<std::size_t, D>::leaf(trees.back().get_weight(), trees.back().get_data());
            std::cout << left.get_data();
            trees.pop_back();
            std::cout << trees.size();
            auto right = utils::WeightedBinaryTree<std::size_t, D>::leaf(trees.back().get_weight(), trees.back().get_data());
            trees.pop_back();
            auto parent = utils::WeightedBinaryTree<std::size_t, D>::complex(&left, &right);
            std::cout << "IM ENTERING";
            utils::insert_in_isorted(trees, parent);
            for (int i = 0 ; i < trees.size() ; i++)
                std::cout << trees[i].get_weight() << " ";  
        }
#

I get the two last items each time from the vector

#

and I try to create a complex tree from them

#

but it does that error to me

rancid pilot
#

The problem is likely in the WeightedBinaryTree class itself, as I wrote above. Sadly I have to get back to work now. Maybe someone else can help you.

sinful kayak
#

[leaf('b',6),leaf('c',5),leaf('b',4)]
so if I had this I'd chain up leaf('c',5) and leaf('b',4) into complex(leaf('c',5),leaf('b',4))

#

I guess no one is helping sadly 😢