本文介绍了尽管有析构函数调用,但内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究类LinkedList,它看起来像这样:

I'm working on a class LinkedList which looks like this:

private:
    LL_element* first;
    LL_element* last;
    int size;
public:
    //constructor
    Linkedlist(): first(NULL), last(NULL), size(0) {}

    //destructor
    ~Linkedlist();

    //adds element at the end of the list.
    void push_back(int value);

    //removes an element at the end of the list.
    bool pop_back(int& value);

函数push_back创建一个新的LL_element对象(动态分配).函数pop_back显式删除列表末尾的元素.只要列表不为空,析构函数将使用函数pop_back.问题是当我创建一个Linkedlist对象时:

The function push_back creates a new LL_element object (dynamically allocated).The function pop_back explicitly deletes the element at the end of the list.The destructor uses the function pop_back as long as the list is not empty.The problem is that when I create a Linkedlist object:

Linkedlist foo =   Linkedlist();
foo.push_back(3);
foo.push_back(5);

当foo超出范围时,将调用析构函数,但是Visualstudio仍然为我提供了LL_elements的内存泄漏.但是,当我动态分配时:

When foo goes out of scope the destructor is called, but Visualstudio still gives me memoryleaks of the LL_elements. However when I dynamically allocate:

Linkedlist* foo = new Linkedlist();
foo->push_back(3);
foo->push_back(5);

然后使用"delete"调用析构函数,VS不会泄漏内存.

And then call the destructor with 'delete', VS does not give memoryleaks.

在堆栈上创建Linkedlist时,编译器是否正确调用了析构函数,或者未正确使用默认构造函数?是真的让我感到困惑...

Is the destructor not properly called by the compiler or is the default constructor not properly used when creating a Linkedlist on the stack? It's reallyconfusing me...

push_back和pop_back的代码:

The code for push_back and pop_back:

bool Linkedlist:: pop_back(int& value) {

//only if the list is not empty, an element can be removed.
if(!this->is_empty()) {

    value = this->last->get_value();
    LL_element* removed = this->last;
    this->last = removed->get_previous();

    if(this->size!=1) {
    this->last->set_next(NULL);
    }

    delete removed;
    size--;
    return true;
}

value = 0;
cout << EMPTY_LIST_MESSAGE << endl;
return false;}

void Linkedlist:: push_back(int value)
{

LL_element* to_add = new LL_element(value);

//if there already is a first element, we can ignore it
if(!this->is_empty()) {

    this->last->set_next(to_add);
    to_add->set_previous(last);
    this->last = to_add;
    size++;

}

//if the list is empty --> special case.
else {

    this->first = to_add;
    this->last = to_add;
    size++;

}
}

SSCCE:

int main(int argc, const char * argv[]) {

Linkedlist foo;
foo.push_back(3);
foo.push_back(5);
foo.push_back(6);
foo.push_back(7);
_CrtDumpMemoryLeaks();
return 0;
}

输出:

Detected memory leaks!
Dumping objects ->
{139} normal block at 0x00A58148, 12 bytes long.
 Data: <            > 00 00 00 00 00 81 A5 00 07 00 00 00
{138} normal block at 0x00A58100, 12 bytes long.
 Data: <H           > 48 81 A5 00 B8 80 A5 00 06 00 00 00
{137} normal block at 0x00A580B8, 12 bytes long.
 Data: <     0      > 00 81 A5 00 F0 30 A5 00 05 00 00 00
{136} normal block at 0x00A530F0, 12 bytes long.
 Data: <            > B8 80 A5 00 00 00 00 00 03 00 00 00
Object dump complete.
The program '[5592] linkedlist.exe' has exited with code 0 (0x0).

推荐答案

您正在检查foo超出范围之前的内存泄漏,因此它没有机会调用其析构函数,这反过来可能会清除所有LL_elements(假设,因为您尚未发布析构函数代码).像这样尝试:

You are checking for memory leaks before foo goes out of scope, so it doesn't have a chance to call its destructor which in turn probably clears all LL_elements (assumption, since you haven't posted destructor code). Try it like this:

int main(int argc, const char * argv[]) {
    {
        Linkedlist foo;
        foo.push_back(3);
        foo.push_back(5);
        foo.push_back(6);
        foo.push_back(7);
    }
    _CrtDumpMemoryLeaks();
    return 0;
}

这篇关于尽管有析构函数调用,但内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-20 19:08
查看更多