istream_iterator泄漏内存

时间:2010-07-18 19:26:19

标签: c++ memory-leaks operator-overloading istream-iterator

好吧,你们对我的上一个问题非常有帮助,所以我会尝试另一个问题。这也是家庭作业,虽然最后一个很老,但已经提交并等待标记。所以,如果有什么东西会咬我,那可能就是这个问题。我已经混淆了班级名称,因为它仍然可以提交作业(对于其他学生)。

我有一个类,其唯一成员是指向Object的指针。构造此类是为了从它当前持有的指针中公开某些操作 - Object *o_Object{1, 2, 3, ...}的基类。现在,我可以在没有任何内存泄漏或崩溃的情况下执行以下操作。

std::vector<ObjectPtr> v;
v.push_back(ObjectPtr(new Object1(..., ..., ...)));
v.push_back(ObjectPtr(new Object2(..., ...)));
v.push_back(ObjectPtr(new Object1(.., .., ..)));

// Copy Constructor Ptr
std::vector<ObjectPtr> v2(v);
// Assignment Operator Ptr
std::vector<ObjectPtr> v3;
v3 = v2;

这一切都有效,并且没有内存泄漏。但是,如果我尝试从带有istream_iterator<ObjectPtr>的文件中读取内容,它就会开始泄漏。 ObjectPtr是唯一处理动态内存的类,Object *o_可以设置为NULL或由Object{1, 2, 3, ...}分配。

要读取的文件如下所示

Object1
...
...
Object2
...
...
Object1
..
std::ifstream is("file.txt");
std::istream_iterator<ObjectPtr> in(is), end;
for (; in != end; ++in)
    cout << *in << "\n";

用于读取这些值的ObjectPtr中的朋友函数类似于

friend istream &operator>>(istream &is, ObjectPtr &op) {
    std::string tmp;
    while (std::getline(is, tmp)) {
        if (tmp == "Object1") {
            op.o_ = new Object1;
            return is >> (Object1 &)*(op.o_); // Send it to operator>> for Object1
        }
        if (tmp == "Object2") {
            op.o_ = new Object2;
            return is >> (Object2 &)*(op.o_);
        }
        ...
    }
    return is;
}

在这里的某个地方开始对我进行独角兽,我真的很想知道为什么。

简而言之 - 当赋值和复制构造函数正常工作时,istream_iterator会泄漏内存,这使我相信类Object{1, 2, 3, 4, ..}构造正确,并且问题可以在operator>>中找到。< / p>

1 个答案:

答案 0 :(得分:2)

这是我发生的第一件事。我不知道你是否正在寻找这个问题:

friend istream &operator>>(istream &is, ObjectPtr &op) {
    std::string tmp;
    while (std::getline(is, tmp)) {
        if (tmp == "Object1") {
            op.o_ = new Object1;

在最后一行中,op.o中的旧值会发生什么变化? 请记住,流入对象意味着流入完全构造的对象,您必须记住对象的旧数据。 (这就是为什么经常更喜欢使用std::istream构造函数。对于保护初始化的复杂对象,该对象将在下一刻被更改。)

ObjectPtr是否有赋值运算符或swap()成员函数?如果是这样,通过构造一个新对象并将其分配给/ op来交换它可能更容易实现输入操作符。