istream_iterator утечка памяти - PullRequest
0 голосов
/ 18 июля 2010

Хорошо, вы, ребята, очень помогли с моим последним вопросом, поэтому я попробую другой. Это также домашнее задание, и хотя последнее было довольно старым, оно было отправлено и ожидает отметки. Так что если есть что-то, что меня укусит, то, вероятно, это будет проблемой. Я запутал имена классов и так далее, так как все еще можно отправить задание (для других студентов).

У меня есть класс, единственным членом которого является указатель на объект. Этот класс создан для предоставления определенных операций из указателя, который он содержит в данный момент - 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>>.

1 Ответ

2 голосов
/ 18 июля 2010

Вот первое, что происходит со мной.Я не знаю, ищите ли вы эту проблему:

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. Для сложных объектов, которые сохраняют инициализацию для объекта, который должен быть изменен в ближайший момент.)оператор присваивания или swap() функция-член?Если это так, может быть проще реализовать оператор ввода, создав новый объект и назначив его / поменяв его местами с op.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...