【问题标题】:Delete a Linked List before closing a C++ program?在关闭 C++ 程序之前删除链接列表?
【发布时间】:2014-01-20 15:21:42
【问题描述】:

我有一个疑问如下...

链表处理指针和动态分配。所以他们提供了一个关键字new,它在 heap 存储中分配一块内存(我想这就是它的拼写方式)并返回一个指向它的指针。他们还提供了delete 关键字,用于释放new 返回的指针所指向的内存。

假设我已经创建了一个包含 10 个 节点 的链接列表,那么我是否必须创建一个函数来扫描每个节点并删除每个节点?因为在我的教科书中,他们写道,如果您不删除动态分配的对象,则会导致内存泄漏...

所以简而言之,我是否必须在关闭 C++ 控制台应用程序之前扫描每个节点并删除每个节点??


其他细节

操作系统 Windows 7

编译器 Turbo C++

【问题讨论】:

  • 程序关闭前?严格来说,不会。但这样做是一种很好的做法。
  • @MitchWheat" 别把这个可怜的家伙弄糊涂了。
  • @John Dibling:我不是。这是 100% 正确的。
  • 所以你认为我是个可怜的人,嗯??
  • @TheDreamCoder17:我在开玩笑。

标签: c++


【解决方案1】:

对于分配的每个内存,如果不再使用,则有一个类或函数负责释放它,这是一个很好的做法。

当程序关闭时,所有程序使用的内存都会被操作系统释放。但我认为你的老师(不是家庭作业吗?)或老板宁愿你释放内存。

底线是:delete 您使用new 创建的所有内容。

【讨论】:

    【解决方案2】:

    所以简而言之,我是否必须扫描每个节点删除每个节点 在关闭 C++ 控制台应用程序之前??

    当然你可以在关闭你的问题之前delete它,如果你没有delete它,那么operating system无论如何都会清除你的应用程序/程序消耗的内存。

    曾经,如果你知道,你的heap 内存对delete 没什么用处(而不是等待关闭程序)

    {
      Allocation with new...
      call function(using allocated memory)
      ....
      ....
      call function2(using allocated memory)
    
      not using allocated memory here after..
      **Delete Your heap memory..**
    
      call AnotherFunction()
      ....
      ...
    
      Alternatively, you can release / delete memory here also. (Good practice than not deleting :) )
      end of main / application.
    }
    

    【讨论】:

      【解决方案3】:

      不,你实际上没有这样做。

      然而,几乎所有代码都应该以这样一种方式编写,即当拥有它的对象超出范围时数据会被删除,因此这将(几乎)不可避免地发生。

      换句话说,你应该通常有类似的东西:

      // WARNING: bad code. Avoid this, or anything similar.
      struct node {
          int data;
          struct node *next;
      };
      
      node *head = NULL;
      
      int main() { 
           node *t = new node;
           t->data = 1;
           t->next = head;
           head = t;
      
           t = new node;
           t->data = 2;
           t->next = head;
           head = t;
      
           // here, do we bother to delete the two nodes or not?
      };
      

      相反,您通常想要做的是创建一个封装所有工作的类,并在其析构函数中释放它拥有的所有内存:

      class linked_list {
          struct node { 
              int data;
              node *next;
      
              node(int data, node *next = NULL) : data(data), next(next) {}    
          } *root;
      public:
          void add(int data) {
              root = new node(data, root);
          }
      
          ~linked_list() { 
             node *prev = root;
             for (node *temp = prev->next; temp!=NULL; temp=temp->next) {
                  delete prev;
                  prev = temp;
             }
             delete prev;
          }       
      };
      

      有了这样的课程,真的不需要做决定:

      int main() { 
          linked_list x;
      
          x.add(1);
          x.add(2);
      }
      

      当执行到达定义x 的块的末尾时,x 超出范围并被销毁。在这个过程中,它的析构函数被调用,并删除了链表中的节点(当然,以我的代码中的任何错误为模)。在这种情况下,无需考虑或关心删除节点是否有意义,因为它每次都会自动发生。

      请注意,我也不是说这段代码(甚至接近)100% 理想。使用足够现代的编译器来支持它,您几乎肯定希望它成为允许存储任意类型的模板,并使用unique_ptrmake_unique 而不是原始指针和原始new。不幸的是,我别无选择,只能将这些排除在外,因为我确信 Turbo C++ 不支持unique_ptr,并且怀疑它是否也支持模板。对于实际使用,这还应该包括一个复制构造函数和赋值运算符,因此分配和复制链表将正常工作(就目前而言,这通常会导致问题,因为它最终会试图破坏节点链表两次)。

      最后一点:当然,您通常不应该编写自己的链表代码。但是,当/如果您确实有理由编写容器(或类似的东西)时,它应该清理自己的烂摊子,可以这么说。 C++ 的真正优势之一是确定性破坏。使用它。

      【讨论】:

        猜你喜欢
        • 2022-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-20
        • 2013-03-29
        • 2011-05-05
        • 2021-07-17
        • 1970-01-01
        相关资源
        最近更新 更多