vendredi 29 juillet 2016

free memory vector of smart pointers

i am a C++ beginner and just started using smart pointers of c++11. In my code i have a vector with std::unique_ptr to an Object called Partition (which i declared by myself).

I use this vector of partitions for a binary search and want to delete the vector and its partition upon end of the method.

As i understood, the unique_ptr is a smart pointer build around the usage in a single reference like my vector. If the vector cannot reference to the Partition anymore, the garbage collector will free the memory of the Partition object.

So far so good. But what is the correct way of removing the vector? Shall i just call it's clear method, and if so will this dereference the Partition object? Will there still be reserved memory for the vector?

Here is my Partition class

class Partition {
public:
    Partition(lemon::UnionFind components, std::vector<Graph::Node> v1, std::vector<Graph::Node> v2)
    : components(components), v1(v1), v2(v2) {}

    const lemon::UnionFind get_components() {
        return components;
    }

    const std::vector<Graph::Node> get_v1() {
        return v1;
    }

    const std::vector<Graph::Node> get_v2() {
        return v2;
    }

    bool is_activated() {
        return activated;
    }

    void mark() {
        this->marked = true;
    }

    void unmark() {
        this->marked = false;
    }

    void flip_activation_status(){
        this->activated = !this->marked;
    }


private:
    lemon::UnionFind components;
    std::vector<Graph::Node> v1;
    std::vector<Graph::Node> v2;
    bool activated;
    bool marked;
};

and here the binary search method which receives a vector of unique_ptr and should release the partitions as well as the reserved memory for the vector afterwards.

std::vector<Graph::Node> binary_fvs_search(std::vector<std::unique_ptr<Partition>> partitions, Graph graph) {

        // get lower bound
        int left = 0; // todo from lower bound

        // get upper bound
        int right = 10; // todo from upper bound

        int middle = (int) (left + floor((right - left) / 2));

        // helper variables
        bool found_solution;
        int best_result_length = std::numeric_limits<int>::max();
        std::vector<Graph::Node> result;
        std::vector<Graph::Node> best_result;

        // as long as we have searchspace left between left and right
        while(left < right){
            // init best result to 0 and found solution to false for this iteration
            best_result_length = 0;
            found_solution = false;

            // cycle through all partitions
            for(std::vector<std::unique_ptr<Partition>>::iterator p = partitions.begin(); p != partitions.end(); p++){
                // only feedback activated partitions
                if((**p).is_activated()) {

                    // call feedback on this partition and the current k = middle
                    // if feedback cannot find a solution it throws value = 0
                    try {
                        result = feedback(graph, (**p).get_v1(), (**p).get_v2(), (**p).get_components(), middle);
                    } catch (int value) {
                        // no solution for feedback mark partition to deactivate
                        if(value == 0) {
                            (**p).mark();
                        }
                        continue;
                    }

                    // tell flag that we found a solution for k = middle
                    found_solution = true;

                    // remember best result
                    if(result.size() < best_result_length) {
                        best_result = result;
                    }
                }
            }

            // we found a solution for k = middle
            if(found_solution) {
                // deactivate all marked partitions
                for(std::vector<std::unique_ptr<Partition>>::iterator p = partitions.begin(); p != partitions.end(); p++)
                {
                    (**p).flip_activation_status();
                }

                // change borders and middle
                right = left;
                middle = (int) (left + floor((right - left) / 2));
            }
        }

        // clear the partitions
        partitions.clear();
        return best_result;
    }

any feedback on this code is appreciated.

best, rap3

Aucun commentaire:

Enregistrer un commentaire