swittuth
swittuth

Reputation: 87

Copy Constructor for Class Linked List not working

My copy constructor is referring to another address instead of copying the values, can you guys please find the problem for me?

This is the copy constructor:

Poly::Poly(const Poly& copyList)
{

    // copy the first term
    power = copyList.power;
    coef = copyList.coef;

    if (copyList.nextTerm == NULL)
    {
        nextTerm = NULL;
    }
    else
    {
        // copy the next term
        PolyPtr trackCopy = copyList.nextTerm;
        nextTerm = new Poly;
        PolyPtr trackOriginal = nextTerm;
        PolyPtr newTerm;

        while (trackCopy != NULL)
        {
            newTerm = new Poly;
            newTerm->coef = trackCopy->coef;
            newTerm->power = trackCopy->power;
            trackOriginal->nextTerm = newTerm;
            trackOriginal = newTerm;

            trackCopy = trackCopy->nextTerm;

        }   
    }

}

copyList here is a class with private member variables as coef, power and a nextTerm that refers to the next node of the list

Here are is the interface of Poly:

class Poly
{
    public:
        // constructors
        Poly();
        Poly(int constant);
        Poly(int coef, int power);
        Poly(const Poly& copyList);

        // set functions
        void setPower(int number);
        void setCoef(int number);
        void setNextTerm(Poly* link);

        // member function to compute
        int evaluate(int x);


    private:
        int power;
        int coef;
        Poly* nextTerm;

};
typedef Poly* PolyPtr;

An example is here:

int main()
{
    PolyPtr polyNomial = new Poly(2, 3);
    PolyPtr nextTerm = new Poly(5, 8);

    polyNomial->setNextTerm(nextTerm);

    PolyPtr copyTerm(polyNomial);

    PolyPtr newTerm = new Poly(1, 2);
    copyTerm->setNextTerm(newTerm);

    cout << copyTerm->evaluate(3) << endl;

    cout << polyNomial->evaluate(3) << endl;


    return 0;
}

Here I expected the evaluation of the copyTerm and polyNomial to be different but they are the same

Upvotes: 0

Views: 90

Answers (1)

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

Your copy constructor has a bug. I added this friend function to display the linked list and a small program to create Polys and to copy them:

std::ostream& operator<<(std::ostream& os, const Poly& p) {
    const Poly* n = &p;
    os << '{';
    do {
        os << "addr:" << n << ' ' << n->power << ',' << n->coef << ' ';
        n = n->nextTerm;
    } while(n);
    return os << '}';
}

int main() {
    Poly p(1,2);
    p.setNextTerm(new Poly(3,4));

    std::cout << "orig: " << p << '\n'; // display the original
    Poly c(p);                          // copy construction
    std::cout << "copy: " << c << '\n'; // display the copy
}

Note the extra Poly with zeroes inserted in the copy:

orig: {addr:0x7ffcf2af8cd0 2,1 addr:0x1447eb0 4,3 }
copy: {addr:0x7ffcf2af8ce0 2,1 addr:0x1448ee0 0,0 addr:0x1448f00 4,3 }

If you simplify the copy constructor like this:

Poly::Poly(const Poly& rhs) : power(rhs.power), coef(rhs.coef), nextTerm(nullptr) {
    for(Poly *prev = this, *next = rhs.nextTerm; next; next = next->nextTerm) {
        prev->nextTerm = new Poly(next->coef, next->power);
        prev = prev->nextTerm;
    }
}

The output will be something like this instead:

orig: {addr:0x7ffdfe4b2eb0 2,1 addr:0x1f15eb0 4,3 }
copy: {addr:0x7ffdfe4b2ec0 2,1 addr:0x1f16ee0 4,3 }

Upvotes: 3

Related Questions