I need help with debugging a class I wrote to store a polynomial into a linked list. I can compile my code with no errors or warnings, but during runtime, my program crashes. I just got back a pretty bad grade on this assignment for school, and in the notes it was returned with, I was told that I have errors in my copy constructor and destructor. However after comparing my copy constructor to some examples I found online for a linked list copy constructor I am not sure where my problem is.
Here is my header file that defines my polynomial class.
#include <iostream>
#include <iomanip>
#include <stdlib.h>
usingnamespace std;
// Here the user can specify a different type
typedefint coefType;
typedefint exponentType;
class Poly
{
public:
// Constructor: create an empty polynomial linked list.
Poly();
// Copy constructor: create a deep copy
Poly(const Poly& original);
// Destructor: deallocate memory that was allocated dynamically
~Poly();
// Get corresponding coefficient for an exponent
coefType getCoef(exponentType exponent);
// Set the coefficient for an exponent
void setCoef(exponentType exponent, coefType coef);
// Find the term for an exponent, returns a pointer to the term.
// If there is no term with that exponent, make a new term and set
// the coefficient to zero.
void findTerm(exponentType exponent);
// Insert a new term. This is placed directly after the current
// item.
void newTerm(exponentType exponent, coefType coef);
// Overloaded assignment operator
Poly& operator = (const Poly& orig);
// Find the highest exponent in the polynomial
exponentType findDegree();
// Overloaded math operators
Poly operator+(const Poly& orig);
Poly operator*(const Poly& orig);
// Sotring and simplifying
void sort();
void simplify();
private:
// List node, called polyTerm for Polynomial Term
struct polyTerm
{
coefType coef;
exponentType exponent;
polyTerm *next;
};
// Points to the first term
polyTerm *head;
// Points to the current term – the tail end term of the linked list
polyTerm *current;
};
And here is part of my source file that implements my polynomial class.
// This is the copy constructor
Poly::Poly(const Poly & original)
{
// Create a temporary struct to hold/read the data being copied from the given polynomial to the new one
polyTerm *temp = NULL;
// If the given polynomial linked list is empty, return an empty polynomial linked list
if (original.head == NULL)
{
head = NULL;
current = NULL;
}
else
{
head = new polyTerm;
current = head;
temp = original.head;
// Step through the linked list
while (current->next != NULL)
{
current->coef = temp->coef;
current->exponent = temp->exponent;
if (temp->next == NULL)
current->next = NULL;
else
{
current->next = new polyTerm;
current = current->next;
temp = temp->next;
}
}
}
delete temp; // preventing memory leak here
temp = NULL;
}
// This is the destructor
Poly::~Poly()
{
// Create a struct to temporarily store position information
polyTerm *temp = NULL;
current = head;
// Step through the linked list from first to last node and delete node-by-node
while (current != NULL)
{
temp = current->next;
delete current;
current = temp;
}
delete temp; // Preventing memory leak here
temp = NULL;
delete head; // Preventing memory leak here
head = NULL;
}
If I could get pointed in the right direction as to how I can fix my code, I would really appreciate it. (No pun intended)
Thanks.
Have you tried using your IDE's built-in debugger to step through the code?
Also, may I ask why you are using linked lists in the first place? They are only beneficial when you have very large data stored in them; they're not that useful with modern hardware nowadays.
My IDE is Visual Studio. My main function accepts a filename as a command line argument and reads in the polynomial data from a txt file. I'm not sure how debug in Visual Studio when I have to pass a command line argument and where I would put the txt file so that Visual Studio could use it.
In your project properties, the Debugging section lets you specify the command line arguments to pass to your program. You can also set the working directory here, which is where relative paths will start from.
I'll be sure to try that, thanks. In the meantime, if anyone is able to spot anything in my logic that looks wonky, that would help, but I know I don't have any syntactical errors. Or if anyone has any questions about part of my code, I'll try to explain it.
As for why I'm using linked lists for this, it was part of an assignment at school to teach us about dynamic memory allocation and linked lists. Our last assignment was creating a Matrix ADT using arrays. Since the assignment I'm asking about here was already returned with a grade, I see no harm in asking about what I did wrong and correcting it.
line 19 in your copy contructor code doesn't look quite right. You're new-ing a polyTerm struct (uninitialized), pointed to by head, and then setting current to point to the same struct. You're then trying to use this uninitialized struct to work out whether or not to continue your while loop.
The contents of the while loop a bit suspect, too -- but I didn't delve into it. The while loop needs to walk the "original" list.
And there's a rogue delete at the end of the constructor. temp points at a node in the "original" list, which the new list has no right to delete!
Destructor
You've already deleted all nodes in the while loop so the extra deletes (for temp and head) are going to be trying to re-delete nodes. Esp. if there was only a single node in the list.
Also, it would be better not to reuse current, which should be called tail, going by the comment in your header file. (Actually, if you renamed the member to tail you could then use currentas the name of a local variable.)
And nulling temp and head could be omitted as it's a destuctor.