Хорошо, вы, ребята, очень помогли с моим последним вопросом, поэтому я попробую еще один. Это также домашнее задание, и, хотя последний был довольно старым, он был отправлен и ждет, чтобы его отметили. Поэтому, если есть что-то, что меня укусит, это, вероятно, будет эта проблема. Я обфускал имена классов и т. Д., Так как все еще можно отправить задание (для других студентов).istream_iterator утечка памяти
У меня есть класс, единственным членом которого является указатель на объект. Этот класс построен для выделения определенных операций из указателя, который он удерживает в настоящий момент, - 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;
}
Где-то здесь он начинает unicorning на меня, и мне очень хотелось бы знать, почему.
В двух словах - istream_iterator утечки памяти во время присваивания и конструктор копирования работает должным образом, что приводит меня к мысли, что классы Object{1, 2, 3, 4, ..}
построены правильно, и проблема должна быть найдена в operator>>
.
О, человек .. Вы сделали мой день - удалите op.o_; Спасибо Спасибо спасибо! – citizencane
@citizancane: Обратите внимание, что вам все равно нужно следить за этим членом 'o' во многих других местах. Как насчет назначения? Прописи строительство? Действительно, я предпочел бы реализовать 'operator >>()' в терминах других членов (как я написал в своем ответе), чем дублировать весь этот код вручную, играя с динамически выделенным объектом. – sbi
Думая об этом еще раз, я мог бы даже разделить «ObjectPtr» на два класса, поскольку он (по крайней мере) имеет две вещи: (A) он управляет динамически распределенным объектом и (B) он служит в качестве прокси-сервера при работе с этим объект. Если вы разделите (A) на подходящий класс интеллектуальных указателей, внедрение (B) станет намного проще и чище. – sbi