使用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的指针成员在复制构造函数,复制指定和析构函数中得到正确的管理。

链接地址: http://www.djcxy.com/p/40657.html

上一篇: Memory leak with std::string when using std::list<std::string>

下一篇: Is it possible to introduce Automatic Reference Counting (ARC) to C++?