title: double link list using smart pointers
body: <p>I just read up about smart pointers so i wanted to do a real demo example, hence i created the DLL code below, the problem is the nodes are placed properly and all, but nodes memory are not getting freed, not sure what i am doing wrong.
  as far as my understanding , when the scope runs out, the nodes must be deleted automatically. please correct me if i am wrong.</p>
  
  <p>Original Code:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;memory&gt;
  using namespace std;
  
  template &lt;typename T&gt;
  class DLL {
          class Node {
              public:
                  T key;
                  std::shared_ptr&lt;Node&gt; next;
                  std::shared_ptr&lt;Node&gt; prev;
                  Node():key(),next(),prev(){}
                  Node(T data):key(data),next(),prev(){}
                  ~Node(){ 
                      cout &lt;&lt; "node deleted \n";
                  }
          };
          std::shared_ptr&lt;Node&gt; m_head;
          std::shared_ptr&lt;Node&gt; m_tail;
          std::size_t length;
  
      public:    
          DLL() : m_head() ,m_tail() , length(0){
          }
          virtual ~DLL(){
          }
          void add_back(T data){
              std::shared_ptr&lt; Node &gt; node = std::make_shared&lt;Node&gt;(data);
              if(!m_tail){
                  m_tail = std::move(node);
                  m_head = m_tail;
              }
              else{
                  m_tail-&gt;next = std::move(node);
                  m_tail-&gt;next-&gt;prev = m_tail;
                  m_tail = m_tail-&gt;next;
              }
              length++;
          }
          void add_front(T data){
              std::shared_ptr&lt; Node &gt; node = std::make_shared&lt;Node&gt;(data);
              if(!m_head){
                  m_head = std::move(node);
                  m_tail = m_head;
              }
              else{
                  m_head-&gt;prev = std::move(node);
                  m_head-&gt;prev-&gt;next = m_head;
                  m_head = m_head-&gt;prev;
              }
              length++;
          }
          void printNodes(void){
              for(std::shared_ptr&lt; Node &gt; temp = m_head; temp ; temp = temp-&gt;next) {
                  cout &lt;&lt; temp-&gt;key &lt;&lt; '\n';
              }
          }
          void addAtPosition(T data , std::size_t pos){
              if(pos &lt; 0 || pos &gt;= length) {
                  throw("Invalid position");
              }
              if(pos == 0){
                  add_front(data);
              }
              else if(pos == length - 1){
                  add_back(data);
              }
              else{
                  std::shared_ptr&lt; Node &gt; temp = m_head;
  
                  for(; temp  &amp;&amp; pos ; temp = temp-&gt;next) {
                      pos--;
                  }
  
                  std::shared_ptr&lt; Node &gt; node = std::make_shared&lt;Node&gt;(data);
                  std::shared_ptr&lt; Node &gt; prev = temp-&gt;prev;
  
                  temp-&gt;prev = std::move(node);
                  temp-&gt;prev-&gt;next = temp;
                  temp-&gt;prev-&gt;prev = prev;
                  prev-&gt;next = temp-&gt;prev;
                  length++;
              }
          }
  };
  int main(int argc , char** argv){
      std::unique_ptr&lt;DLL&lt;int&gt;&gt; m_list = std::make_unique&lt;DLL&lt;int&gt;&gt;();
      m_list-&gt;add_front(3);
      m_list-&gt;add_front(2);
      m_list-&gt;add_front(1);
      m_list-&gt;add_back(4);
      m_list-&gt;add_back(5);
      m_list-&gt;add_back(6);
      m_list-&gt;addAtPosition(7,0);
      m_list-&gt;addAtPosition(7,4);
      m_list-&gt;addAtPosition(7,7);
      m_list-&gt;printNodes();
      return 0;
  }
  </code></pre>
  
  <p>Modified Code:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;memory&gt;
  using namespace std;
  
  template &lt;typename T&gt;
  class DLL {
      class Node {
          public:
              T key;
              std::shared_ptr&lt;Node&gt; next;
              std::weak_ptr&lt;Node&gt; prev;
              Node():key(),next(),prev() {}
              Node(T data):key(data),next(),prev() {}
              ~Node(){cout &lt;&lt; "deleted \n";}
      };
      std::shared_ptr&lt;Node&gt;   m_head;
      std::weak_ptr&lt;Node&gt;     m_tail;
      std::size_t length;
  
      public:
          DLL():m_head(),m_tail(),length(0){}
  
          void addFront(T data){
              std::shared_ptr&lt; Node &gt; node = std::make_shared&lt;Node&gt;(data);
              if(length == 0){
                  m_head = std::move(node);
                  m_tail = m_head;
              }
              else{
                  node-&gt;next   = m_head;
                  m_head-&gt;prev = node;
                  m_head = std::move(node);
              }
              length++;
          }
          void addBack(T data){
              std::shared_ptr&lt; Node &gt; node = std::make_shared&lt;Node&gt;(data);
              if(length == 0){
                  m_head = std::move(node);
                  m_tail = m_head;
              }
              else{                
                  node-&gt;prev = m_tail.lock();             
                  node-&gt;prev.lock()-&gt;next = std::move(node);
                  m_tail = m_tail.lock()-&gt;next;
              }
              length++;
          }
          void addAtPosition(T data , std::size_t pos){            
              if(pos == 0){
                  addFront(data);
              }
              else if(pos == length){
                  addBack(data);
              }
              else if(pos &lt; 0 || pos &gt;= length) {
                  throw("Invalid position");
              }
              else{
                  std::shared_ptr&lt; Node &gt; node = std::make_shared&lt;Node&gt;(data);
                  std::weak_ptr&lt;Node&gt; temp = m_head;
  
                  for(int cnt = 0; cnt &lt; pos ; cnt++){
                      temp = temp.lock()-&gt;next;
                  }
                  node-&gt;next = temp.lock();
                  node-&gt;prev = node-&gt;next-&gt;prev;
                  node-&gt;prev = std::move(node);
                  length++;
              }
          }
          void printNodes(void){
              std::weak_ptr&lt;Node&gt; wp = m_head;
              for(int i = 0; i &lt; length; i++) {
                  auto&amp; sp = *(wp.lock());
                  cout &lt;&lt; sp.key;
                  wp = sp.next;
              }
          }
  };
  int main(){
      std::unique_ptr&lt;DLL&lt;int&gt;&gt; m_list = std::make_unique&lt;DLL&lt;int&gt;&gt;();
      for(int i = 0; i &lt; 10 ; i++)
      {
          try{
              m_list-&gt;addAtPosition(i,i);
          }
          catch(const char* mess){
              cout &lt;&lt; i &lt;&lt;' '&lt;&lt;mess &lt;&lt; '\n';
          }
  
      }
      m_list-&gt;printNodes();
      return 0;
  }
  </code></pre>
  
  <p>PS: Based on the input i have edited my code and its now working, but still i feel my methods are doing too much work and there is scope of optimization. can someone help me in optimizing my code using smart pointers. Also i am not trying to implement DLL, i just wrote enough code to get a hands-on feel using the new smart pointers.</p>