Can't figure out why I am getting a segmentation fault

I've looked over my code top and bottom, and I am at a loss. I really have no idea what is causing my code to crash. I am beginning to think that a part of my code I think is working is messing with memory in some other place... I really don't know.

This is the class I am working on:

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
#ifndef _POLY_H_ 
      #define _POLY_H_ 
      
#include <iostream>
#include <cmath>

using namespace std;

const unsigned timeout = 200;
const unsigned displayPrecision = 3;
      
class polynomial
{
    double* fx;
    unsigned polyDegree;
    double* critPnts;
    unsigned numCritPnts;
    double* realRoots;
    unsigned numRealRoots;
    bool endRight;
    bool endLeft;
    polynomial* deriv;
    
    
    
public:
    void derivative();
    polynomial();
    polynomial(const double*, unsigned);
    polynomial(const polynomial&);
    ~polynomial();
    polynomial fPrime(unsigned);
    double f();
    void write();
    
    friend ostream& operator<< (ostream& os, const polynomial& p);
};

#endif 


poynomial.cpp
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
#include "polynomial.h"

polynomial::polynomial()
:fx(NULL), polyDegree(0),critPnts(NULL), numCritPnts(0), realRoots(NULL), numRealRoots(0), endRight(false), endLeft(false), deriv(NULL){}

polynomial::polynomial(const double* func, unsigned l)
:polyDegree(l),critPnts(NULL), numCritPnts(0), realRoots(NULL), numRealRoots(0), deriv(NULL)
{
    fx =  new double[l];
    
    for(int i = 0; i <= l; i++)
    {
        fx[i] = func[i];
    }
}

polynomial::polynomial(const polynomial& f)
:critPnts(NULL), polyDegree(f.polyDegree), realRoots(NULL), numCritPnts(0), numRealRoots(0), endRight(false), endLeft(false), deriv(NULL)
{
    fx = new double(f.polyDegree + 1);
    
    for(int i = 0; i <= polyDegree; i++)
    {
        fx[i] = f.fx[i];
    }
}

polynomial::~polynomial()
{
    polynomial* temp = this;
    
    do
    {
        delete[] temp->fx;
        delete[] temp->critPnts;
        delete[] temp->realRoots;
        temp = temp->deriv;
    } while (temp != NULL);   
}

void polynomial::derivative()
{
    
    if (polyDegree == 1)
    {
        return;
    }
    
    deriv = new polynomial;
    
    deriv->fx =  new double[polyDegree];
    deriv->polyDegree = polyDegree-1;
    
    
    for(int i = 1; i <= polyDegree; i++)
    {
        deriv->fx[i-1] = fx[i] * i;
    }
    
    cout << *deriv << endl;
    deriv->derivative();
}

polynomial polynomial::fPrime(unsigned prime)
{
    polynomial* temp;
    polynomial* temp2;
    
    if (deriv == NULL)
    {
        this->derivative();
    }
    
    temp =  this;
    
    for (int i = 0; i < prime; i++)
    {
        temp = temp->deriv;
        
        if (temp == NULL)
        {
            return *temp;
        }
    }
    
    temp2 = new polynomial;
    temp2->fx =  new double[temp->polyDegree + 1];
    temp2->polyDegree =  temp->polyDegree;
    
    for(int i = 0; i <= temp->polyDegree; i++)
    {
        temp2->fx[i] = temp->fx[i];
    }
    
    return *temp2;
}

double polynomial::f()
{
}

void polynomial::write()
{
}

ostream& operator<< (ostream& os, const polynomial& p)
{
    if (p.polyDegree == 1)
    {
        os << p.fx[1] << "x ";
        if (p.fx[0] > 0)
        {
            os << "+ " << p.fx[0];
        }
        else
        {
            os << "- " << (p.fx[0]) *-1;
        }
        
        return os;
    }
    
    if (p.polyDegree == 0)
    {
        if (p.fx != NULL)
        {
            os << p.fx[0];
        }
        
        return os;
    }
        
    os << p.fx[p.polyDegree] << "x" << p.polyDegree << " ";
        
    for (int i = p.polyDegree -1; i >= 2; i--)
    {
        if (p.fx[i] > 0)
        {    
            os << "+ " << p.fx[i] << "x" << i << " ";
        }
        else
        {
            os << "- " << (p.fx[i])* -1 << "x" << i << " ";
        }
    }
    
    if (p.fx[1] > 0)
    {
        os << "+ " << p.fx[1] << "x ";
    }
    else
    {
        os << "- " << (p.fx[1]) *-1 << "x ";
    }
    
    if (p.fx[0] > 0)
    {
        os << "+ " << p.fx[0];
    }
    else
    {
        os << "- " << (p.fx[0]) * -1;
    }
    
    return os;
}


main.cpp
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
#include <iostream>
#include "polynomial.h"

void fun(const polynomial&);

int main()
{
    double test[5] = {1.0,-2.0,3.0,-4.0,5.0};
    
    polynomial p(test, 4); 
    polynomial p2;
    
    cout << p << endl;
    
    p.derivative();
    
    fun(p);
    
    cout << p.fPrime(2);
    
    cin.get();
    
    return 0;
}

void fun(const polynomial& p)
{
    polynomial g;
    
    cout << p << endl;
}


The part of the program causing the crash is this member function. If I comment this code out the program seems to work just fine.
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
polynomial polynomial::fPrime(unsigned prime)
{
    polynomial* temp;
    polynomial* temp2;
    
    if (deriv == NULL)
    {
        this->derivative();
    }
    
    temp =  this;
    
    for (int i = 0; i < prime; i++)
    {
        temp = temp->deriv;
        
        if (temp == NULL)
        {
            return *temp;
        }
    }
    
    temp2 = new polynomial;
    temp2->fx =  new double[temp->polyDegree + 1];
    temp2->polyDegree =  temp->polyDegree;
    
    for(int i = 0; i <= temp->polyDegree; i++)
    {
        temp2->fx[i] = temp->fx[i];
    }
    
    return *temp2;
}


If I comment out a line in the destructor that deletes fx*, the program will not crash. I have no idea why that is. Something is happening when I create a new polynomial and have my polynomial pointer temp2 try and access it and return it, but I don't know how or why its causing a segmentation fault. The output when this program is run is exactly what I am expecting. The function works but someplace there is a memory issue.

The purpose of this program is to return the 1st, 2nd, 3rd, 4th or whatever derivative of the polynomial that was called. Each polynomial has a pointer as a member that points to another polynomial which is its derivative.

I really need some help on this one. Stared at it for a couple hours but can't figure out what is going on.
It looks like in some cases fx is allocated using [] and in other places (). If this is the case then delete [] with most definitely crash.
That destructor looks very wrong.

fx is allocated, depending on which constructor is used, by either new[] or new. The delete in the destructor must match the call to new.

Line 20 in polynomial.cpp allocates space for one double and initializes it to f.polyDegree+1. I don't think that's what you meant to do since you then go on to treat it as if it's an array of size polyDegree+1.

You have a memory leak in polynomial::fPrime(). You allocate memory via new and then throw away the address.

The destructor, after a short review of the code, looks like it should be (assuming you fix the one constructor):

1
2
3
4
5
6
7
polynomial::~polynomial()
{
    delete [] fx ;
    delete [] critPnts ;
    delete [] realRoots ;
    delete derivative ;
}


You don't actually allocate any memory for critPnts or realRoots, but it looks like you may in the future, and they will clearly be array type allocations. And, since it is perfectly okay to call delete on null pointers, there's no reason not to include them in the destructor.

However, there should be no loop in the destructor. The polynomial you new'd for derivative is responsible for deleting it's own members. If you recursively delete them in the destructor you're going to be deleting the same pointer values multiple times and that's a recipe for undefined behavior.
Last edited on
Thank you guys so much! Such a simple fix and such a big problem. If I could trouble you a little more, what is the difference between

pointer = new type[];

as compared to

pointer = new type();

cire I appreciate your critique of my method. Given that, for the goals I have for the class, it would make sense to keep a polynomials derivative in memory, how would you suggest solving this problem? Would it be most proper to call derivative every time I need a derivative and then deallocate in the same step? Seems costly in terms of performance.

Thanks again. That was driving me nuts.
The first is invalid. You need to have a number between the [ ].

If that is the case, then:

pointer = new type[n]; will create an array of n types and return a pointer to the first element.
pointer = new type(); will create a single type and return a pointer to it.
pointer = new type[];

as compared to

pointer = new type();


Well, the first allocates memory for an array of type variables and constructs them in-place via the default constructor.

The second allocates memory for one type variable and constructs it in that memory via the default constructor. Any time you use new type(args), the compiler will try to forward those arguments to a type constructor after the memory is allocated to construct the object.

Given that, for the goals I have for the class, it would make sense to keep a polynomials derivative in memory, how would you suggest solving this problem?


There's nothing wrong with what you've done. If you're referring to the fPrime function you don't need to use new there at all.

1
2
3
    polynomial temp ;
    // manipulate temp
    return temp ;


would work fine.
1
2
3
4
5
//polynomial::fPrime
        if (temp == NULL)
        {
            return *temp;
        }
You are purposely dereferencing an invalid pointer.
Last edited on
Topic archived. No new replies allowed.