считывание массива из потока

287
20 ноября 2017, 20:18

Нужно перегрузить оператор считывания из потока для шаблонного класса. В шаблонном классе Set есть поле - массив элементов другого шаблонного класса Point:

class Set
{
public:
    Set()
    {
        _ptr = nullptr;
        _capacity = 0;
        _size = 0;
    }
    Set(int capacity)
    {
        _ptr = new classType[capacity];
        _capacity = capacity;
        _size = 0;
    }
    template<class classType>
    friend ostream& operator << (ostream& os, const Set<classType>& set);
    template <class classType>
    friend istream& operator >> (istream &stream, Set<classType>& set);
}
class Point
{
public:
    Point()
    {
        _x = 0;
        _y = 0;
        _z = 0;
    }
    Point(T x, T y, T z)
    {
        _x = x;
        _y = y;
        _z = z;
    }
    template<typename T>
    friend ostream& operator << (ostream& os, const Point<T>& p);
    template<typename T>
    friend istream& operator >> (istream &stream, Point<T>& p);
}

сама реализация:

    template <class classType>
istream &operator >> (istream &stream, Set<classType>& set)
{
    cout << "Enter capacity: ";
    stream >> set._capacity;
    cout << "Enter size: ";
    stream >> set._size;
    cout << "Enter elements: ";
    for (int i = 0; i < set._size; ++i)
        stream >> set._ptr[i];
    return stream;
}
template <typename T>
istream &operator >> (istream &stream, Point<T>& p)
{
    stream >> p._x >> p._y >> p._z;
    return stream;
}

происходит вылет из gtest-ов после считывания capacity b size и начала считывания первого элемента из _ptr (_ptr[0])

скриншот тестов:

Подскажите, что делать?

Answer 1

Как минимум у вас УЖЕ есть Set, в который вы считываете. С выделенной памятью (боюсь, нулевой - если вы создали его без параметра).

При чтении вы просто перезаписываете поля _capacity и _size, тем самым уже нарушая внутреннее состояние объекта - он-то считает, что у него выделена память для _capacity элементов и записано _size элементов. Но вы уже нарушили согласованность объекта.

А потом еще и начинаете записывать в память данные. Вы уверены, что _ptr указывает на достаточное количество выделенной памяти? Особенно если перед вызовом объявили просто Set<Type> set;?

Ситуация понятна?

READ ALSO
Правильна ли такая функция?

Правильна ли такая функция?

Всех приветствуюТолько начал разбираться с функциями

248
Итератор с шагом

Итератор с шагом

Собственно нужно сделать считывания из multimap c определённым шагом

212
std::string vs std::wstring в русскоязычном приложении

std::string vs std::wstring в русскоязычном приложении

Поскольку в свое время плавно переехал с чистого C на С++/Qt, то все проблемы unicode остались за кадром, скрытые внутри QStringТеперь при переходе...

242
Эффективно найти средний элемент в set&#39;е

Эффективно найти средний элемент в set'е

std::set обычно представлен бинарным деревом поискаУ него есть методы begin и end, которые позволяют получить минимум и максимум, а также lower_bound и upper_bound...

259