c++ - istream_iterator 内存泄漏

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

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

我有一个类,它的唯一成员是一个指向对象的指针。这个类被构造为从它当前持有的指针公开某些操作 - 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;
}

这里的某个地方它开始对我 unicorn ,我真的很想知道为什么。

简而言之 - istream_iterator 在分配和复制构造函数正常工作时泄漏内存,这让我相信类 Object{1, 2, 3, 4, ..}构造正确,问题出在operator>>内.

最佳答案

这是我想到的第一件事。我不知道这是否是您要寻找的问题:

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 交换它可能更容易实现输入运算符。

关于c++ - istream_iterator 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3276906/

相关文章:

c++ - Armadillo 读MAT文件报错

java stackoverflowerror 在无限循环中抛出

c++ - 运算符重载添加两个对象错误

c++ - 如果模板参数确实如此,则仅重载运算符

c++ - 如何在此回调中用具有编译时类型检查的内容替换 void 指针?

c++ - 难以理解链表实现(结构部分)?

javascript - 如何修复这个 Javascript 内存泄漏

android - Jit:将 JitTable 的大小从 512 调整为 1024 等等……这是什么?

c++ - operator<< 重载、 namespace 和模板

c++ - 将 std::list 转换为 char*[size]