使用std :: list <std :: string>时使用std :: string存在内存泄漏
我在当前项目中使用std::list<std::string>
。 但是有一处与此相关的内存泄漏。 所以我已经单独测试了有问题的代码:
#include <iostream>
#include <string>
#include <list>
class Line {
public:
Line();
~Line();
std::string* mString;
};
Line::Line() {
mString = new std::string("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
}
Line::~Line() {
//mString->clear(); // should not be neccessary
delete mString;
}
int main(int argc, char** argv)
{
// no memory leak
while (1==1) {
std::string *test = new std::string("XXXXXXXXXXXXXXXXXXXXXXXX");
delete test;
}
// LEAK!
// This causes a memory overflow, because the string thats added
// to the list is not deleted when the list is deleted.
while (1==1) {
std::list<std::string> *sl = new std::list<std::string>;
std::string *s = new std::string("XXXXXXXXXXXXXXXXXXXXXXX");
sl->push_back(*s);
//sl->pop_back(); //doesn't delete the string?- just the pointer
delete sl;
}
// LEAK!
// Here the string IS deleted, but the memory does still fill up
// but slower
while (1==1) {
std::list<Line> *sl = new std::list<Line>;
Line *s = new Line();
sl->push_back(*s);
//sl->pop_back(); //does delete the Line-Element
sl->clear();
delete sl;
}
return 0;
// this does not cause any noticable memory leak
while (1==1) {
std::list<int> *sl = new std::list<int>;
int i = 0xFFFF;
sl->push_back(i);
sl->clear();
delete sl;
}
return 0;
// This does not cause any overflow or leak
while (1==1) {
int *i;
i= new int [9999];
delete[] i;
}
}
为什么我的字符串列表导致内存泄漏? 不应该删除列表导致每个包含的字符串上调用析构函数?
在第一种情况下, list
类不知道您是否使用new
分配了字符串,并且无法删除它。 特别是,该列表只包含您传入的字符串的副本。
类似地,在第二种情况下,你从未释放线对象s
,因此你泄漏内存。 内部字符串被删除的原因是因为您没有正确实施复制构造函数。 因此,如果您制作Line
对象的副本,则它们都会引用相同的字符串指针,并且如果您尝试删除它们,则会遇到麻烦。
您的Line类需要一个copy-ctor和一个正确处理字符串指针的赋值操作符。
或者,只需要一个std::string
成员而不是一个指针,并让string
类处理内存(就是这样)。
这是你的泄漏:
while (1==1) {
std::list<Line> *sl = new std::list<Line>;
Line *s = new Line();
sl->push_back(*s);
//sl->pop_back(); //does delete the Line-Element
sl->clear();
delete sl;
}
STL集合按值存储元素,为其分配和释放空间。 您分配的内容必须明确发布。 只需在循环结尾添加delete s
即可。
如果您必须存储指针,请考虑存储托管指针(如boost::shared_ptr
,或者查看Boost指针容器库。
在第二面,你根本不需要在堆上分配Line
。 只需将其更改为:
sl->push_back(Line());
和其他人一样,确保Line
的指针成员在复制构造函数,复制指定和析构函数中得到正确的管理。
上一篇: Memory leak with std::string when using std::list<std::string>
下一篇: Is it possible to introduce Automatic Reference Counting (ARC) to C++?