尽管有析构函数调用,但内存泄漏
Memory leaks despite destructor call
我正在处理一个 class LinkedList,它看起来像这样:
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 对象时:
Linkedlist foo = Linkedlist();
foo.push_back(3);
foo.push_back(5);
当 foo 超出范围时,调用析构函数,但 Visualstudio 仍然给我 LL_element 的内存泄漏。但是当我动态分配时:
Linkedlist* foo = new Linkedlist();
foo->push_back(3);
foo->push_back(5);
然后用'delete'调用析构函数,VS不给memoryleaks。
是编译器没有正确调用析构函数还是在堆栈上创建链表时没有正确使用默认构造函数?是真的
把我弄糊涂了...
push_back和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(假设,因为您还没有发布析构函数代码)。像这样尝试:
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;
}
我正在处理一个 class LinkedList,它看起来像这样:
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 对象时:
Linkedlist foo = Linkedlist();
foo.push_back(3);
foo.push_back(5);
当 foo 超出范围时,调用析构函数,但 Visualstudio 仍然给我 LL_element 的内存泄漏。但是当我动态分配时:
Linkedlist* foo = new Linkedlist();
foo->push_back(3);
foo->push_back(5);
然后用'delete'调用析构函数,VS不给memoryleaks。
是编译器没有正确调用析构函数还是在堆栈上创建链表时没有正确使用默认构造函数?是真的 把我弄糊涂了...
push_back和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(假设,因为您还没有发布析构函数代码)。像这样尝试:
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;
}