Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unique_ptr with polymorphic type not being deleted

Tags:

c++

unique-ptr

I have a vector of unique_ptrs to a derived type store using the base class

std::unique_ptr<std::vector<std::unique_ptr<Variable>>> decisionVariables;

Where Variable is the superclass and the derived type is a Route class. My problem is that the route instances do not seem to get removed when the class containing the decisionVariables is deleted.

Route is derived from Variable:

#ifndef __VARIABLE__
#define __VARIABLE__

/**
 * Interface for decision variables. 
 */

#include <cstring>
#include <ostream>
#include <memory>

class Variable {

    public:
        /**
         * Returns an independent copy of this decision variable.
        *
        * @ret a copy of this decision variable
         */
        virtual std::unique_ptr<Variable> copy () = 0;

        virtual std::string toString () = 0;
};

#endif

Header file for Route:

#ifndef __ROUTE__
#define __ROUTE__

#include <vector>
#include <map>
#include <cstring>
#include <sstream>
#include <ostream>
#include <memory>
#include <set>
#include <algorithm>

#include "../../../Framework/h/core/Variable.h"

class Route : public Variable {

private:
    std::unique_ptr<std::vector<int>> route;
    double frequency;
    double routeLength;

public:
    Route ();
    void add (int);
    void addToFront (int);
    void remove ();
    void removeFromFront ();
    std::vector<int>::iterator begin();
    std::vector<int>::iterator end();
    int size ();
    std::vector<int> getViableNodes (std::shared_ptr<std::map<int, std::unique_ptr<std::vector<int>>>>, int);
    int front ();
    int back ();
    std::string toString ();
    int get (int);
    bool containsLink (int, int);
    bool contains (int);
    void replace (int, int);
    void setFrequency (double);
    double getFrequency ();

    void setRouteLength (double);
    double getRouteLength ();

    std::unique_ptr<Variable> copy ();
};

#endif

Is there a way to prevent the severe memory leak experienced at the moment?

like image 436
Matt Avatar asked Aug 09 '13 17:08

Matt


People also ask

Can you delete a unique_ptr?

An explicit delete for a unique_ptr would be reset() . But do remember that unique_ptr are there so that you don't have to manage directly the memory they hold. That is, you should know that a unique_ptr will safely delete its underlying raw pointer once it goes out of scope.

What happens when unique_ptr goes out of scope?

std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.

Can unique_ptr be copied?

A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr , passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved.


1 Answers

Your abstract base class Variable doesn't have a virtual destructor, so you can't delete an object of a derived class using a pointer to that class. That is exactly what unique_ptr<Variable> will try to do when it is destroyed.

This will result in undefined behaviour - the most likely behaviour is that the derived class's destructor isn't called, so any resources it manages will leak.

The simplest fix is a virtual destructor in the base class:

virtual ~Variable() {}
like image 71
Mike Seymour Avatar answered Oct 01 '22 04:10

Mike Seymour