在关闭C ++程序之前删除链接列表?

时间:2014-01-20 15:21:43

标签: c++

我怀疑如下......

链接列表处理指针和动态分配。因此,他们提供了一个关键字new,它在存储中分配一个块(这就是我猜的拼写方式)并返回指向它的指针。并且它们还提供了delete关键字,该关键字释放了新指针返回的指针所指向的内存。

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

因此,在关闭C ++控制台应用程序之前,我必须扫描每个节点删除每个节点吗?


Aditional Details

操作系统 Windows 7

编译器 Turbo C ++

3 个答案:

答案 0 :(得分:2)

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

当程序关闭时,程序使用的所有内存仍将由操作系统释放。但我认为你的老师(作业,不是吗?)或老板宁愿你释放记忆。

最重要的是:delete您使用new创建的所有内容。

答案 1 :(得分:1)

  

因此,我必须扫描删除每个节点的每个节点   在关闭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.
}

答案 2 :(得分:0)

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

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

换句话说,通常应该具有以下内容:

// 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而不是原始指针和raw {{1 }}。不幸的是,我别无选择,只能将它们排除在外,因为我确信Turbo C ++不支持new,并且怀疑它是否支持模板。对于实际使用,这也应该包括复制构造函数和赋值运算符,因此分配和复制链接列表将正常工作(因为它现在,通常会导致问题,因为它最终会试图破坏节点中的节点链表两次)。

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