删除后持久链接列表项

时间:2012-08-26 23:46:27

标签: c++ linked-list delete-operator

我编写了一个双向链表(在这种情况下存储素数),我在使用列表后尝试删除的元素。我在列表的析构函数中编写了一个简单的循环。但是,我可以在删除后打印每个元素中保存的值。释放内存后,我预计会出现“错误访问”错误。此外,我使用Activity Monitor在程序执行的各个点显示正在使用的资源。创建链表时(显然)内存使用量大幅增加,但在调用析构函数后也有小幅增加。我认为有些事情是错误的。

正在为列表的每个成员调用'delete'语句,但它似乎没有做任何事情。我已经在下面的析构函数中包含了相关的代码。列表和元素使用'new'语句创建。 'current','head'和'tail'标签是指向列表元素(节点)的指针。

PrimeList::~PrimeList()
{
    // delete list elements
    do
    {
        current = tail;
        tail = tail->previous;
        delete current;
    }
    while( tail != NULL );

    // nullify the pointers
    head = NULL;
    tail = NULL;
    current = NULL;

    // reset size
    size = 0;
}

任何见解?

5 个答案:

答案 0 :(得分:2)

删除对象不一定会改变对象占用的内存,更不用说让后续访问的内存不可用了。有多种方法可以确保您的程序不会访问已删除的内存,例如使用调试分配器以不常见的位模式覆盖已删除的内存,或者使用动态分析工具(如valgrind)。

答案 1 :(得分:1)

删除元素后访问元素是一个错误。当然,带有错误的代码将无法像您期望的那样工作。这就是为什么我们试图避免这样的代码。

你的析构函数看起来很好。最有可能的是,正在发生的事情是,你的析构函数内部只是让内存可以重用。由于您没有更改其内容或分配任何新对象,因此它“恰好具有”相同的内容。

答案 2 :(得分:1)

您是否通过引用将列表的头部传递给了删除方法?

否则,您只是尝试删除列表的副本,以便在您尝试访问列表时列表仍然存在。

我看不到你的整个代码,但是对于析构函数,你应该做这样的事情:

PrimeList::~PrimeList()
{
  deleteList( &head); // pass the reference to the head pointer
}

void PrimeList::deleteList( struct node** headRef)
{
  struct node* head = *headRef;
  // now apply your deletion algorithm
}

答案 3 :(得分:1)

所有delete所做的是使对象使用的内存可供另一个对象重用(并调用析构函数,如果有的话)。它不会擦除内存或将其标记为无法使用或其他任何内容(至少,它不能保证 - 它可能会感觉像它)。在将来某个时间内存可能被分配给另一个对象,此时它将被覆盖。

delete内存未返回给系统,您的进程会保留该内存以供将来new(以及malloc,...)重用。这就是为什么Activity Monitor仍然认为你正在使用那个内存。有更好的方法可以确定您是否正确地释放了列表,搜索“c ++内存泄漏检测器”或其他类似的内容。

答案 4 :(得分:1)

您的编译器很可能是“帮助您”。在链表中实现析构函数的一种好方法是递归。假设列表中的每个条目都有一个类Node,

class Node {
    public:
    ~Node() {delete this->next;}
};

PrimeList::~PrimeList() {
    delete head;
}