Copy Constructor not working

I know I am doing something wrong with memory, but I can't exactly seem to find that mistake. When I run my copy constructor, a segmentation fault occurs. Can anyone help me figure out what I am doing wrong please? Thank you!

I have provided the interface and implementation files for the Polynomial class as well as a test program. I really apologize if my code is difficult to read at the moment.

Polynomial.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
    File: Polynomial.h
    Description: The interface header file for the Polynomial class. Each node of the linked list represents a power with a coefficient (ex: 3x^2). Constructors, member functions, and operator overloading functions have been included.
*/

#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H

#include <iostream>
using namespace std;

struct PolyNode
{
    int power; // Represents the power of x
    int coefficient; // Represents the coefficient corresponding to the power of x
    PolyNode* node; // Pointer of the structure type that will be utilized as the main linked list.
};

typedef PolyNode* PolyPtr; // Now, PolyPtr is the same thing as PolyNode*

class Polynomial
{
    private:
        PolyPtr poly; // Variable of the pointer type.
        int calculate_coefficient(string& poly_temp, string symbol); // Extra function that calculates the coefficient based on the sign (+ or -).
        void remove_nodes(PolyPtr parameter); // Extra function that will delete a selected node.
    public:
        Polynomial(); // Default constructor
        Polynomial(const Polynomial& original); // Copy constructor
        Polynomial(int); // Constructor that produces the polynomial that has only one constant term
        Polynomial(int,int); // Constructor that produces the 1-term polynomial whose coefficient and exponent are given by the 2 arguments.
        ~Polynomial(); // Destructor
        void insert_polynomial(); // Lets the user input the polynomial, and the function returns that linked list to the user.
        void make_lists(int constant, int exponent); // Inserts the polynomial into a node of the linked list.
        void return_polynomial(); // Outputs the polynomial to the user.
        Polynomial operator =(const Polynomial& right); // If the copy constructor and destructor were defined, it is highly recommended that the assignment operator is overloaded.
        friend Polynomial operator +(const Polynomial& left, const Polynomial& right); // Overloading the plus operator.
        friend Polynomial operator -(const Polynomial& left, const Polynomial& right); // Overloading the minus operator.
        friend Polynomial operator *(const Polynomial& left, const Polynomial& right); // Overloading the multiplication operator.
        int evaluate(int value); // Evaluates the polynomial at that value.
};

#endif 
Polynomial.cpp (Part 1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
    File: Polynomial.cpp
    Description: The implementation file for the Polynomial class.
*/

#include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include "Polynomial.h"
using namespace std;

Polynomial::Polynomial() : poly(NULL)
{
}

Polynomial::Polynomial(const Polynomial& original)
{
    if (original.poly != NULL)
    {
        for (PolyPtr i = original.poly; i != NULL; i = i->node)
	{
	    make_lists(i->coefficient, i->power);	
	}
    }
    else
    {
        poly = NULL;
    }
}

Polynomial::Polynomial(int constant)
{
    PolyPtr temp = new PolyNode;
    temp->power = 0;
    temp->coefficient = constant;
    poly = temp;
}

Polynomial::Polynomial(int constant, int exponent)
{
    PolyPtr temp = new PolyNode;
    temp->power = exponent;
    temp->coefficient = constant;
    poly = temp;
}

Polynomial::~Polynomial()
{
    if (poly != NULL) // if the linked list isn't empty...
    {
        for (PolyPtr i = poly; i->node != NULL; i = i->node)
        {
            remove_nodes(i);
        }
    }
}

void Polynomial::remove_nodes(PolyPtr parameter)
{
    if(poly != NULL)
    {
        PolyPtr before = NULL, discard = NULL;
        for(PolyPtr i = poly; i != NULL; i = i->node)
        {
            if(i->node == parameter)
            {
                before = i;
            }
            else if(i == parameter)
            {
                if(i == poly)
                {
                    discard = poly;
                    poly = poly->node;
                    delete discard;
                }
                else
                {
                    discard = i;
                    before->node = discard->node;
                    delete discard;
                }
            }
        }
    }
}

void Polynomial::insert_polynomial()
{
    string polynomial, current, symbol = "+";
    int value = 0, exp = 0;
    cout << "Type in the polynomial in the format ax^n + bx^(n-1) + ..." << endl;
    cout << "Write the # symbol right at the end of the polynomial. (Ex: 6x^3 + 4x^2 + 32#; 6x^2 + 3x + 32#)" << endl;
    getline(cin,polynomial);     
    string temp = polynomial.substr(0); // Make a temporary substring that is equal to the polynomial received in the input.

    for (int i = 0; i < polynomial.length(); i++)
    {
        if (polynomial[i] == ' ') // If there is a blank space...
        {
            current = temp.substr(0, temp.find(" ")); // create a temporary substring up to the point of the space...
            temp = temp.substr(temp.find(" ") + 1); // and cut off that part of the string from the main substring.
            if (current == "+" || current == "-") // If the temporary substring is a symbol instead of a polynomial...
            {
                symbol = current;
            }
            else
            {
                value = calculate_coefficient(current, symbol); // Calls the function that will calculate the coefficient.
                if (string::npos != current.find("^")) // If the ^ character exists in the string (which means a power greater than 1 exists)...
                {
                    exp = atoi(current.substr(current.find("^") + 1).c_str()); // Convert the string after the ^ character into an int.
                }
                else
                {
                    exp = 1; // Set exponent equal to 1 if there is no ^ character existing in the string.
                }
                make_lists(value, exp); // Give the coefficient and power to a function that will place those values in a node.
            }
        }
        if (string::npos != temp.find("#") && i == polynomial.length() - 1) // If the # character exists in temp and the end of the polynomial is reached...
        {
            temp = temp.substr(0, temp.find("#")); // Create a substring that cuts off the # character.
            if (string::npos != temp.find("x")) // If the "x" character exists (aka not a constant)...
            {
                value = calculate_coefficient(temp, symbol);
                if (string::npos != temp.find("^"))
                {
                    exp = atoi(temp.substr(temp.find("^") + 1).c_str());
                }
                else
                {
                    exp = 1;
                }
            }
            else // If the value is a constant (aka no "x" character found)...
            {
                value = calculate_coefficient(temp, symbol);
                exp = 0;
            }
            make_lists(value, exp);
        }
    }
    cout << endl;
}

int Polynomial::calculate_coefficient(string& poly_temp, string symbol)
{
    int string_to_int;
    // If the symbol before the polynomial is positive and a variable x exists...
    if (symbol == "+" && (string::npos != poly_temp.find("x")))
    {
        string_to_int = atoi(poly_temp.substr(0, poly_temp.find("x")).c_str()); // Cut off the part after the "x" character and convert that part from string to int.
        if (string_to_int == 0)
        {
            if (string::npos != poly_temp.find("-"))
            {
                string_to_int = -1;
            }
            else
            {
                string_to_int = 1;
            }
        }
    }
    // If the symbol before the polynomial is negative and a variable x exists...
    else if (symbol == "-" && (string::npos != poly_temp.find("x")))
    {
        string_to_int = atoi(poly_temp.substr(0, poly_temp.find("x")).c_str()) * -1; // Same as above if-statement, but this time, the int is multiplied by -1.
        if (string_to_int == 0)
        {
            string_to_int = -1;
        }
    }
    // Same thing but x doesn't exists (aka the value is a constant)...
    else if (symbol == "+" && (string::npos == poly_temp.find("x")))
    {
        string_to_int = atoi(poly_temp.c_str()); // Just convert the constant to an int.
    }
    // Same thing as above if-statement but the sign is different...
    else if (symbol == "-" && (string::npos == poly_temp.find("x")))
    {
        string_to_int = atoi(poly_temp.c_str()) * -1; // Same as above if-statement, but this time multiply by -1.
    }
    return string_to_int;
}
Well holy shit thats lots of code.
Last edited on
Polynomial.cpp Part 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
void Polynomial::make_lists(int constant, int exponent)
{
    if (poly == NULL)
    {
        poly = new PolyNode;
        poly->coefficient = constant;
        poly->power = exponent;
        poly->node = NULL;
    }
    else
    {
        PolyPtr temp = new PolyNode;
        temp->coefficient = constant;
        temp->power = exponent;
        temp->node = NULL;
        
        PolyPtr i = poly;
        while (i->node != NULL && i->power > exponent)
        {
            i = i->node;
        }
        if (i->power == exponent)
        {
            i->coefficient += constant;
            if (i->coefficient == 0)
            {
                remove_nodes(i);
            }
            delete temp;
        }
        else if (i->power > exponent)
        {
            temp->node = i->node;
            i->node = temp;
        }
        else // exponent > i->power
        {
            if (i == poly)
            {
                temp->node = poly;
                poly = temp;
            }
            else
            {
                PolyPtr tmp = poly;
                while (tmp->node != NULL && tmp->node != i)
                {
                    tmp = tmp->node;
                }
                temp->node = i;
                tmp->node = temp;
            }
        }
    }
}

void Polynomial::return_polynomial()
{
    if (poly == NULL) // If there is nothing in the list...
    {
        cout << "The polynomial is 0.\n";
    }
    else
    {
        int count = 0, value, exp;
        cout << "The polynomial is ";
        for (PolyPtr i = poly; i != NULL; i = i->node)
        {
            value = i->coefficient;
            exp = i->power;
            if (count == 0)
            {
                if (exp > 1 && value != 0)
                {
                    if (value == 1)
                    {
                        cout << "x^" << exp;
                    }
                    else if (value == -1)
                    {
                        cout << "-x^" << exp;
                    }
                    else
                    {
                        cout << value << "x^" << exp;
                    }
                }
                else if (exp == 1 && value != 0)
                {
                    if (value == 1)
                    {
                        cout << "x";
                    }
                    else if (value == -1)
                    {
                        cout << "-x";
                    }
                    else
                    {
                        cout << value << "x";
                    }
                }
                else if (exp == 0 && value != 0)
                {
                    cout << value;
                }
                else
                {
                    cout << "0";
                }
            }
            else
            {
                if (value > 0 && i != NULL)
                {
                    cout << " + ";
                }
                else if (value < 0 && i != NULL)
                {
                    cout << " - ";
                    value *= -1;
                }

                if (exp > 1 && value != 0)
                {
                    if (value == 1)
                    {
                        cout << "x^" << exp;
                    }
                    else
                    {
                        cout << value << "x^" << exp;
                    }
                }
                else if (exp == 1 && value != 0)
                {
                    if (value == 1)
                    {
                        cout << "x";
                    }
                    else
                    {
                        cout << value << "x";
                    }
                }
                else if (exp == 0 && value != 0)
                {
                    cout << value;
                }
                else
                {
                    cout << "0";
                }
            }
            count++;
        }
        cout << endl;
    }
}

int Polynomial::evaluate(int value)
{
    int temp = 0;
    for (PolyPtr i = poly; i != NULL; i = i->node)
    {
        temp += i->coefficient * pow(value, i->power);
    }
    return temp;
}

Polynomial operator +(const Polynomial& left, const Polynomial& right)
{
    Polynomial sum;

    for (PolyPtr i = left.poly; i != NULL; i = i->node)
    {
        sum.make_lists(i->coefficient, i->power);
    }

    for (PolyPtr i = right.poly; i != NULL; i = i->node)
    {
        sum.make_lists(i->coefficient, i->power);
    }

    return sum;
}

Polynomial Polynomial::operator =(const Polynomial& right)
{
    Polynomial left;

    if(right.poly != NULL)
    {
        for(PolyPtr i = right.poly; i != NULL; i = i->node)
        {
            left.make_lists(i->coefficient, i->power);
            make_lists(i->coefficient, i->power);
        }
    }
    else
    {
        left.poly = NULL;
        poly = NULL;
    }

    return left;
}

Polynomial operator -(const Polynomial& left, const Polynomial& right)
{
    Polynomial difference;

    for(PolyPtr i = left.poly; i != NULL; i = i->node)
    {
        difference.make_lists(i->coefficient, i->power);
    }

    for(PolyPtr i = right.poly; i != NULL; i = i->node)
    {
        difference.make_lists(-(i->coefficient), i->power);
    }

    return difference;
}

Polynomial operator *(const Polynomial& left, const Polynomial& right)
{
    Polynomial product;

    for(PolyPtr i = left.poly; i != NULL; i = i->node)
    {
        for(PolyPtr k = right.poly; k != NULL; k = k->node)
        {
            product.make_lists(i->coefficient * k->coefficient, i->power + k->power);
        }
    }

    return product;
}


Test program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include "Polynomial.h"
using namespace std;

int main()
{
    Polynomial test;
    test.insert_polynomial();
    test.return_polynomial();
    Polynomial test2(test);
    test2.return_polynomial(); // Should output the same polynomial that was inputted in test.

    return 0;
}
Can you please copy paste your errors aswell?..

Edit: Also, if you have this much code to show. Please upload them on

http://pastebin.com/

and give us the links.
Last edited on
Sure gimme one second...and really sorry for the long code.
The error is "Cannot access memory address at..."
Copy paste your error.
Edit: I need to fix a couple of errors before uploading the code there...sorry for the delay.

Edit: "Program received signal SIGSEGV, Segmentation fault.
0x0000000000401d6e in Polynomial::return_polynomial() ()"
I'm running this on a Linux system.
Last edited on
Polynomial.h: http://pastebin.com/GKmuMkpe

Polynomial.cpp: http://pastebin.com/k7vfGv3C

polynomial.cpp (Test program): http://pastebin.com/zM14K447

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401d6e in Polynomial::return_polynomial() ()

A segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (for example, attempting to write to a read-only location, or to overwrite part of the operating system).

On Unix-like operating systems, a signal called SIGSEGV is sent to a process that accesses an invalid memory address.

And I think its telling you its happening in Polynomial::return_polynomial()

So look through it. Debug it etc
Last edited on
I was trying to figure out my error. When I was using gdb on Ubuntu, I tried to print out i->coefficient and i->power in the return_polynomial() function, but it says that I can't access that memory location. I tried looking back at how I'm putting my nodes in the list, and I don't think there's any problem with that. All other things work, it's just the copy constructor that I'm trying to fix now. Do you have any ideas on how I can fix this seg fault? I was at this for about 8 hours now.
I don't know what is causing your error, but I am pretty sure that your destructor function isn't working correctly.

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
Polynomial::~Polynomial()
{
    if (poly != NULL) // if the linked list isn't empty...
    {
        for (PolyPtr i = poly; i->node != NULL; i = i->node)
        {
            remove_nodes(i);
        }
    }
}
 
void Polynomial::remove_nodes(PolyPtr parameter)
{
    if(poly != NULL)
    {
        PolyPtr before = NULL, discard = NULL;
        for(PolyPtr i = poly; i != NULL; i = i->node)
        {
            if(i->node == parameter)
            {
                before = i;
            }
            else if(i == parameter)
            {
                if(i == poly)
                {
                    discard = poly;
                    poly = poly->node;
                    delete discard;
                }
                else
                {
                    discard = i;
                    before->node = discard->node;
                    delete discard;
                }
            }
        }
    }
}

I'm not sure exactly how memory addresses will look like so I'm just going to give them letters.

Let's say that you have 2 polynodes, at addresses A and B. In your polynomial, poly points towards the polynode at address A. Your polynomial's destructor function is called and at line 52, you assign poly to i.

At this point, both poly and i point towards address A. Your destructor function calls remove_nodes(i). In the remove_nodes function, since i == poly, you set poly to point at the polynode at address B and delete the polynode at address A. Then you return to your destructor function.

In your destructor function, i still points at address A. You try to set i = i->node but since the polynode at address A was deleted, I don't think this is possible.
I haven't completely read it ..
But I think there is a problem like this :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
using namespace std ;

void foo(int * y)
{
   int * z = y ;

//// Something to do ..

  delete z ;  // Oops 
}



int main()
{
int * x = new int ; 

*x = 6 ;

foo(x);

cout << *x << endl ; // ???

return 0 ;
}




Beware of memory management ..
Deleting a pointer will cause (( All )) the referenced pointers to be allocated ..

Just check it .. specially in ( make_lists ) ...

Maybe it is not your problem ... but just to inform you about this ..

@fg109
I thought I changed that already...I'll take a look again!

@obscure
I can take a look and see...thanks for the suggestion!
I just thought of something that happened when I tried to help someone with trees a week or two ago. It could mean there is something wrong with your make_lists function.

Example code that doesn't work correctly:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>

using namespace std;

struct Node
{
    int val;
    Node *next;
};

void addNode(Node *n, int i)
{
    if (n == NULL)
    {
        n = new Node;
        n->val = i;
        n->next = NULL;
    }
    else if (n->next == NULL)
    {
        Node *temp = new Node;
        temp->val = i;
        temp->next = NULL;
        n->next = temp;
    }
    else
        addNode(n->next, i);
}

void delNode(Node *n)
{
    if (n == NULL)
        return;
    else
        delNode(n->next);
    delete n;
}

void displayNodes(Node *n)
{
    if (n == NULL)
        return;
    else
    {
        cout << n->val << ' ';
        displayNodes(n->next);
    }
}

int main()
{
    Node *root = NULL;
    addNode(root, 1);
    addNode(root, 2);
    addNode(root, 3);
    displayNodes(root);
    delNode(root);
    return 0;
}


It'll work correctly if I did this: void addNode(Node *&n, int i)

Or if I changed the main function to this:

1
2
3
4
5
6
7
8
9
10
11
int main()
{
    Node *root = new Node;
    root->val = 1;
    root->next = NULL;
    addNode(root, 2);
    addNode(root, 3);
    displayNodes(root);
    delNode(root);
    return 0;
}


As you can see, the top part of addNode is very similar to your make_lists.
Last edited on
When you call make_lists() in your copy constructor the pointer poly is uninitialized:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Polynomial::Polynomial(const Polynomial& original)
{
    if (original.poly != NULL)
    {
        for (PolyPtr i = original.poly; i != NULL; i = i->node)
	{
	    make_lists(i->coefficient, i->power);	
	}
    }
    else
    {
        poly = NULL; // either put this first or use an initializer list
    }
}
Topic archived. No new replies allowed.