Search code examples
c++nullpointerexceptionstdvectorpush-back

Does push_back change the structure of type stored in its vector?


I have following 2 classes:

class Core 
{
public:
    Core() : mid(0), fin(0) {}
    Core(std::istream &in)
    {
        read(in);
    }
    virtual ~Core() {}
    Str name() const
    {
        return n;
    }
    virtual double grade() const
    {
        return vec_grade(mid, fin, hws);
    }
    virtual std::istream &read(std::istream &in);

protected:
    std::istream &read_common(std::istream &in);
    double mid, fin;
    Vec<double> hws;
    virtual Core *clone() const
    {
        return new Core(*this);
    }

private:
    friend class Student2;
    Str n;
};

std::istream &Core::read_common(std::istream &in)
{
    in >> n >> mid >> fin;
    return in;
}

std::istream &Core::read(std::istream &in)
{
    read_common(in);
    read_vec(in, hws);
    return in;
}

and

class Student2
{
    Core *cp;

public:
    Student2() : cp(0) {}
    Student2(std::istream &in) : cp(0)
    {
        read(in);
    }
    Student2(const Student2 &s) : cp(0)
    {
        if (s.cp)
            s.cp->clone();
    }
    Student2 &operator=(const Student2 &s);
    ~Student2()
    {
        delete cp;
    }
    std::istream &read(std::istream &in);
    Str name() const
    {
        if (cp)
            return cp->name();
        else
            throw std::runtime_error("uninitialized Student");
    }
    double grade() const
    {
        if (cp)
            return cp->grade();
        else
            throw std::runtime_error("uninitialized Student");
    }
    static bool compare(const Student2 &x, const Student2 &y)
    {
        return x.name() < y.name();
    }
    Core *getPointer() const
    {
        return cp;
    }
};

std::istream &Student2::read(std::istream &in)
{
    delete cp;
    char ch;
    in >> ch;
    if (ch == 'U')
    {
        cp = new Core(in);
    }
    else
    {
        cp = new Grad(in);
    }
    return in;
}

Now the problem is this:

int main()
{
    vector<Student2> v;
    Student2 s(cin);
    v.push_back(s);
    printf("%p\n%p\n", s.getPointer(), v[0].getPointer());
}

output:

0x562fa03b9280
(nil)

Here I get read into object Student2, and the object will have its address. But once I add it to vector by push_back, the same objetc somehow loses (will get null-pointered) its address. I have no idea how does push_back modifies its value, but it should not (because otherwise it gets its value). What does push_back to its values?


Solution

  • It uses the copy-constructor you wrote. This one:

    Student2(const Student2 &s) : cp(0)
    {
        if (s.cp)
            s.cp->clone();
    }
    

    which sets cp to null (0). That is why the copy's cp is null.