尽管有析构函数调用,但内存泄漏 [英] Memory leaks despite destructor call

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

问题描述

我正在研究类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 really confusing 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;
}

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆