DJB
DJB

Reputation: 1

unique_ptr does not call the destructor to free the pointer

I am passing unique_ptr to function and then move the pointer to another unique_ptr, all is working fine as need, but while point is unique_ptr does not call destructor of the when it goes out of scope.

Below is my code. and its output, the code is in eclipse.

enter image description here

#include <iostream>
#include <memory>

using namespace std;

class BaseCcExpander;
class DeriveHandler;
class ExpansionRuleExecuter;
class DeriveType1;

class ParamBase
{
public :

    ParamBase()
    {
        std::cout << "Ctor:ParamBase:\n";
    }
    std::unique_ptr<ExpansionRuleExecuter> paramexpander;
    virtual ~ParamBase()     { std::cout << "Dtor::~ParamBase:\n"; }
    virtual void attachBase(int paramGrp,int paramId,std::unique_ptr<ExpansionRuleExecuter> xbaseExpander);

};

ParamBase* obj;
void ParamBase::attachBase(int paramGrp,int paramId,std::unique_ptr<ExpansionRuleExecuter> xbaseExpander)
{
    std::cout << "In:  ParamBase::attachHandler :\n";
    paramexpander = std::move(xbaseExpander);
}

class ExpansionRuleExecuter
{
public:
    ExpansionRuleExecuter()
    {
        std::cout << "Ctor ExpansionRuleExecuter::ExpansionRuleExecuter:\n" << endl;
    }
    virtual ~ExpansionRuleExecuter(){

        std::cout << "Dtor ~ExpansionRuleExecuter::ExpansionRuleExecuter:\n" << endl;
    }
    virtual void handleExpansion() = 0;

};
class DeriveHandler : public ExpansionRuleExecuter
{
public:
    DeriveHandler()
    {
        std::cout << "Ctor::DeriveHandler:\n" << endl;
    }

     ~DeriveHandler()
    {
        std::cout << "Dtor::~DeriveHandler:\n" << endl;
    }

     void handleExpansion()
     {
         std::cout << "DeriveHandler expanded\n" << endl;
     }
};



ParamBase *obj1;
class BaseCcExpander
{
public:
    BaseCcExpander()
    {
        std::cout << "Ctor::BaseCcExpander:\n" << endl;
    }

    virtual ~BaseCcExpander()
    {
        std::cout << "Dtor::~BaseCcExpander:\n" << endl;
    }

    typedef unique_ptr<ExpansionRuleExecuter> ccHandler;
    BaseCcExpander::ccHandler ccBaseHandler;

    void attachHandler(int paramGrp, int paramId,std::unique_ptr<ExpansionRuleExecuter> xhandler)
    {
        std::cout << "BaseCcExpander::attachHandler:\n" << endl;
        obj1->attachBase(paramGrp,paramId,std::move(xhandler));
    }

};


class DeriveType1 : public ParamBase
{
public :
    DeriveType1()      { std::cout << "Ctor: DeriveType--------1:\n"  << endl;}
    ~DeriveType1()     { std::cout << "Dtor::~DeriveType---------1\n" << endl;}
    void attachBase(std::unique_ptr<ExpansionRuleExecuter> xbaseExpander);
};

BaseCcExpander ccexpander;


int main()
{

    obj1 = new(DeriveType1);
    ccexpander.attachHandler(1,2,std::unique_ptr<ExpansionRuleExecuter>(new DeriveHandler));
    if(obj1->paramexpander.get())
    {
        ExpansionRuleExecuter *expand = obj1->paramexpander.get();
        expand->handleExpansion();
    }
}

Upvotes: 0

Views: 2348

Answers (2)

dkg
dkg

Reputation: 1785

Your variable pointed by obj1 is not deleted, hence its members would not be destroyed until the delete happens and the unique_ptr will remain alive then the destructor will never be called.

You should either call delete on obj1 at the end of your program or use an unique_ptr on it.

Upvotes: 0

R Sahu
R Sahu

Reputation: 206737

You wrote in a comment:

but by is obj1 not destroying even after the program is over as its in the global space, it should destroy.

There is some misunderstanding here. obj1 is destroyed but the object it points to is not deleted when obj1 is destroyed. If the compiler did that, you won't be able to use:

int main()
{
   int i = 10;
   int* ip = &i;
   // You don't want the run time to call the equivalent of
   // delete ip;
   // when the function returns. That will lead to undefined behavior
   // since ip does not point to memory allocated from the heap.
}

When the program ends, the OS reclaims the memory used by the program but that does not mean that it calls the destructor of obj1.

Had the destructor been responsible for releasing resources other than memory, such as network connections, locks on shared files/folders, etc., they will not be released when the program ends without the destructor getting called.

Upvotes: 2

Related Questions