-1

I don't understand why the destructor of ListELement is never call.
I use the class Base as counter, ListELement derive from Base to use the counter.

The Program:

#include <iostream>
#include <random>
#include <functional>

using namespace std;

class Base{
    protected:
    static int count;
};


template <class T>
class ListElement: public Base{

    public:
    ListElement(const T& value): next(NULL), data(value) { count++;}
    ~ListElement() { cout<<"dead:"<<count<<endl;}

    //Setter
    void SetData(const T& value) { data=value; }
    void SetNext(ListElement* elem) { next = elem; }
    //Getter
    const T& GetData() const { return data; }
    ListElement* GetNext() const { return next; } 

    private:
    T data; 
    ListElement* next;
};

int Base::count = 0;

int main(){
    random_device rd;
    default_random_engine generator(rd());
    uniform_int_distribution<int> distribution(1,100);
    auto dice = bind(distribution, generator);

    int nListSize = 1;
    ListElement<int>* nMyList = new ListElement<int>(999);

    ListElement<int>* temp = nMyList;//nMyList is the first element
    for(int i=0; i<10; ++i) {
        ListElement<int>* k = new ListElement<int>(dice()); //New element
        temp->SetNext(k);
        temp = temp->GetNext(); 
        nListSize++;    
    }

    temp=nMyList;
    for(int i=0; i<nListSize; ++i){
        cout<<"Value["<<i<<"]: "<<temp->GetData()<<endl;
        temp = temp->GetNext();
    }

    return 0;
}

This is my output:

Value[0]: 999
Value[1]: 61
Value[2]: 14
Value[3]: 96
Value[4]: 51
Value[5]: 15
Value[6]: 37
Value[7]: 83
Value[8]: 1
Value[9]: 42
Value[10]: 95

If I type echo &? the console return my 0 so everything should be fine.

user72708
  • 1,235
  • 3
  • 13
  • 20

3 Answers3

4

You new a few ListElement<int> but never delete them.

Destructors are automatically called for variables with automatic-storage duration. They aren't for variables for which you manually allocate memory.

If you add the proper delete statements, you'll have the dtors running.

Note: If you absolutely need a pointer, you should look into std::shared_ptr/std::unique_ptr as you'll have the semantics of a pointer, with the memory management done for you, i.e. the pointer will be properly deleted once it's not referenced anywhere.

JBL
  • 12,588
  • 4
  • 53
  • 84
0

For each explicit new call, you will need an explicit delete call unless your ListElement destructor has a loop to delete those nodes.

hlide
  • 237
  • 2
  • 10
0

Because an object created with operator new must be explicitly released using operator delete.

This can be achieved by using facilities from and either changing the type of nMyList to (before C++-11)

std::auto_ptr<ListElement<int> > nMyList(new ListElement<int>(999));

or (from C++11, which deprecates auto_ptr)

std::unique_ptr<ListElement<int> > nMyList(new ListElement<int>(999));

If you insist on not changing the type of nMyList, then

delete nMyList;

at the end of main() will also work (the advantage of smart pointer types being that they destroy the object they manage).

Rob
  • 1,966
  • 9
  • 13