【发布时间】:2018-09-08 15:00:22
【问题描述】:
如何处理 C++ 中模板类的内存泄漏问题?
在这段代码中,我定义了 4 个模板类:
-
node类和linked_list类组成一个双向链表 -
item类和bag类只是组成了另一个双向链表
这些模板类旨在处理各种类的对象。
在main函数中,我先创建了一个linked_list<string>和一个bag<int>,一切正常。
但是当我尝试创建bag<linked_list<string>> 时,问题就出现了。
我试图回溯看看发生了什么,我看到在bag 类中的函数push_back 中,调用了linked_list 的析构函数,它删除了输入v 中的所有数据。我不知道为什么会这样。
请注意,我重写了所有类的析构函数,并在主函数中调用了className.~className() 以防止内存泄漏。
它确实可以防止来自ls_1 和bag_1 的内存泄漏。
我不知道我的代码的哪一部分是错误的。有人可以帮帮我吗?
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
//node and linked_list class make up a doubly linked list
template<class T> class node {
public:
T value;
node<T> * next;
node<T> * previous;
node<T>() { next = nullptr; previous = nullptr; }
node<T>(T v) { value = v; next = nullptr; previous = nullptr; }
~node<T>() { delete next; }
};
template<class T> class linked_list { //doubly linked list
public:
node<T> * head;
node<T> * tail;
linked_list<T>() { head = nullptr; tail = nullptr; }
~linked_list<T>() { delete head; }
void push_front(T v) { //insert an item to the front
node<T> * p = new node<T>(v);
p->next = head;
head = p;
if (tail == nullptr) {
tail = p;
}
}
};
//item and bag class just make up another doubly linked list
template<class X> class item {
public:
X value;
item<X> *next;
item<X> *previous;
item<X>(X v) { value = v; next = nullptr; previous = nullptr; }
~item<X>() { delete next; }
};
template<class X> class bag { //just another doubly linked list
public:
item<X> *last;
item<X> *first;
int num_items;
int size() { return num_items; }
bag() { last = nullptr; first = nullptr; num_items = 0; }
~bag() { delete first; }
void push_back(X v) { //insert an item to the back
item<X> * p = new item<X>(v);
if (num_items == 0) {
last = first = p;
}
else {
last->next = p;
p->previous = last;
last = p;
}
num_items++;
last->next = nullptr;
}
};
int main() {
//When using built-in classes (like strings) as input
//there's no problem at all
linked_list<string> ls_1;
ls_1.push_front("David");
ls_1.push_front("John");
bag<int> bag_1;
bag_1.push_back(1);
bag_1.push_back(2);
//Problems arise here when using user defined classes (linked_list) as input
//I traced back and found out that a destructor has been called
//that erases all the data in the input. Donno how that happens
bag<linked_list<string>> bag_string;
bag_string.push_back(ls_1);
//These lines are to prevent the memory leaking
//I overwrote destructors for linked_list and node class
//otherwise there's still memory leaking
ls_1.~linked_list();
bag_1.~bag();
bag_string.~bag();
_CrtDumpMemoryLeaks();
getchar();
getchar();
}
【问题讨论】:
-
不要害怕给代码一些喘息的空间,这不像我们为每行代码支付 0.05 美元。它有助于阅读。
-
请注意,我重写了所有类的析构函数,并在主函数中调用了
className.~className()以防止内存泄漏。显式调用析构函数不是你应该如何防止内存泄漏。 -
在
linked_list和node中都没有指定previous,所以从任何合理的定义来看,它都不是一个“双向链表”,item是@987654341 的完全相同@ -
您的类的 3/5/0 规则被打破(复制构造函数,...)。
标签: c++ templates destructor copy-constructor