Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在关闭C+之前删除链接列表+;节目?_C++ - Fatal编程技术网

C++ 在关闭C+之前删除链接列表+;节目?

C++ 在关闭C+之前删除链接列表+;节目?,c++,C++,我有一个疑问如下 链表处理指针和动态分配。因此,他们提供了一个关键字new,它在堆存储中分配一个内存块(我想这就是它的拼写方式),并返回指向它的指针。他们还提供了delete关键字,该关键字释放了新指针所指向的内存 假设我已经创建了一个包含10个节点的链表,那么我应该创建一个函数来扫描每个节点并删除每个节点吗?因为在我的教科书中,他们写道,如果你不删除一个动态分配的对象,那么它会导致内存泄漏 那么,在关闭C++控制台应用程序之前,我必须扫描每个节点删除每个节点吗?? 传统细节 操作系统Wind

我有一个疑问如下

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

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

那么,在关闭C++控制台应用程序之前,我必须扫描每个节点删除每个节点吗??
传统细节 操作系统Windows 7


编译器Turbo C++

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

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


底线是:
delete
使用
new

创建的所有内容这是一个很好的实践,对于分配的每个内存,如果不再使用,则有一个类或函数负责释放它

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

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

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

确定您可以在关闭问题之前
删除它,如果您没有
删除它,那么
操作系统将清除应用程序/程序消耗的内存

一旦,如果您知道,您的
内存不再有用,最好是
删除它(而不是等待关闭程序)

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

确定您可以在关闭问题之前
删除它,如果您没有
删除它,那么
操作系统将清除应用程序/程序消耗的内存

一旦,如果您知道,您的
内存不再有用,最好是
删除它(而不是等待关闭程序)

不,你实际上不必这么做

然而,几乎所有的代码都应该以这样一种方式编写:当拥有数据的对象超出范围时,数据会被删除,所以这(几乎)是不可避免的

换句话说,您通常不应该有以下情况:

// 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%理想的。有了一个足够现代化的编译器来支持它,您几乎肯定会希望它成为一个模板,允许存储任意类型,并使用
唯一的ptr
使唯一的
而不是原始指针和原始
新的
。不幸的是,我别无选择,只好离开这些,因为我敢肯定,涡轮C++不支持<代码> UnQuyJPTR < /代码>,并且怀疑它也支持模板。对于实际使用,这还应包括复制构造函数和赋值运算符,以便正确地分配和复制链表(目前的情况是,两者都会导致问题,因为它们最终会尝试两次销毁链表中的节点)

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

不,你实际上不必这样做

然而,几乎所有的代码都应该以这样一种方式编写:当拥有数据的对象超出范围时,数据会被删除,所以这(几乎)是不可避免的

换句话说,您通常不应该有以下情况:

// 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\u ptr
m