使用动态分配删除元素的链表中的内存泄漏

时间:2018-11-11 07:06:44

标签: c++ memory-leaks linked-list

我一直在处理链表问题,分别使用指向表头和表尾的两个指针。我遇到的问题如下:

当我想从列表的前面或后面删除时,当使用临时动态分配的节点指针实现相应的类方法时,我会发生内存泄漏,而我无法弄清楚到底是什么引起了问题泄漏。

#include <iostream>

class Node {
   public:
      Node():data(0),ptrNode(nullptr){};
      ~Node() {};

      // declaring the getters and setters
      float getData() const {return data;};
      void setData(float d) {data = d;};
      Node* getNodePtr() const {return ptrNode;};
      void setNodePtr(Node* n){ptrNode = n;};

   private:
      float data;
      Node* ptrNode;
    };


class List {

   private:
      Node * ptrHead;
      Node * ptrTail;


   public:
      List():ptrHead(nullptr),ptrTail(nullptr) {};
      ~List() {};

      void insertAtFront(float x) {
               Node * temp = new Node();
               temp->setData(x);

               if (ptrHead == nullptr) {
                     ptrHead = temp;
                     ptrTail = temp;
               } else {
                     temp->setNodePtr(ptrHead);
                     ptrHead = temp;
               }
      };

      void insertAtBack(float x) {
               Node * temp = new Node();
               temp->setData(x);

               if (ptrHead == nullptr) {
                     ptrHead = temp;
                     ptrTail = temp;
               } else {
                     ptrTail->setNodePtr(temp);
                     ptrTail = temp;
               }
      };

      void removeFromFront() {

               if (ptrHead==nullptr) {  // if list is empty
                    std::cout << "List is already empty" << std::endl;
                    return;
               }

               if (ptrHead==ptrTail) { // if list has one element
                    delete ptrHead;
                    ptrHead = nullptr;
                    ptrTail = nullptr;
                    return;
               }
               // assign current Head to temp, assign next node to head 
               // delete temp
               Node * temp = new Node();
               temp = ptrHead;
               ptrHead = ptrHead->getNodePtr();
               delete temp;
               temp = nullptr;
      };

      void removeFromBack() {

               if (ptrHead==nullptr) {  // if list is empty
                    std::cout << "List is already empty" << std::endl;
                    return;
               }

               if (ptrHead==ptrTail) { // if list has one element
                    delete ptrHead;
                    ptrHead = nullptr;
                    ptrTail = nullptr;
                    return;
               }

               // create two temp Node pointers for this one
               Node * sec2last = new Node();
               Node * last = new Node();

               sec2last = ptrHead;
               last = ptrTail;

               // locate second to last element and assign it to sec2last
               while (sec2last->getNodePtr() != ptrTail) {
                     sec2last = sec2last->getNodePtr();
               }

               ptrTail = sec2last;
               ptrTail->setNodePtr(nullptr);

               delete last;
               delete sec2last;
               last = nullptr;
               sec2last = nullptr;
      };

   };

我在main()中运行以下命令:

// global function that dynamically allocates memory in its scope
// for a linked list
void generateList(int x) {
   if (x<=0) {
      cout << "Give a positive integer!" << endl;
      return;
   }

   List * aList = new List();

   for (int i = 0;i<x;i++) {
      aList->insertAtFront(i+1);
   }

   aList->removeFromBack();  // this causes leaks

   delete aList;
}

// MAIN
int main() {

   for (int i = 0;i<80000000;i++)    
       generateList(1);   // just repeatedly generate dynamic list 
                          // with one element
   return 0;
}

我应该指出,如果我们不为removeFromFront()和removeFromBack()方法中的临时节点动态使用内存分配,则程序可以正常工作。但是,就像我说的那样,我不明白为什么上面的代码会泄漏,这使我丧命。

谢谢!

1 个答案:

答案 0 :(得分:5)

           Node * temp = new Node();
           temp = ptrHead;

这是这里的内存泄漏。您分配了一个新的Node,并将指向它的指针存储在temp中。然后,您覆盖该指针并泄漏刚分配的节点。

           // create two temp Node pointers for this one
           Node * sec2last = new Node();
           Node * last = new Node();

           sec2last = ptrHead;
           last = ptrTail;

在这里您再做一次。为什么要在这里分配新的Node