-
Linked List help needed
I'm having trouble figuring out what is wrong with my program. It compiles fine. I can seem to delete any grade in the list, except for the head. Any other grade deletes fine, and I am able to print out the student and print out the grades and the average, unless I delete the head. Then, it gives some wierd error. I've noticed it will go through the whole delete function, and then when it tries to print up the class or the average after I've deleted the head, it will mess up. If I don't try to print up the class or the average after I've deleted the head, then the program ends fine. The error it gives me is a Windows error, an Unhandled Exception in mainprog.exe:0XC0000005: Access Violation. I have no idea what that is. Anyways, here's the code, hopefully someone can help me figure out what is wrong. My problems are with the grade linked list. I'm not even messing with the student linked list, just trying to get the grade one working for now.
Code:
student.h:
#include <string.h>
#include <iostream.h>
#include <fstream.h>
struct grade {
float data;
grade * next;
};
class student {
private:
char name[30];
grade* gradelist; //linklist of grades
float average;
student* next;
public:
student();
student(char tname[]);
student(char tname[], grade *tgradelist, float taverage);
void addgrade(float); //insert a grade at the head of the list
void avegrades(); //calculate the average of the list of grades
//of a student
void deletegrade(float); //search for a grade in a list and del it
void printstudent();
friend class compclass;
};
student.cpp:
#include "student.h"
student::student() {
strcpy(name,"\0");
average = 0.0;
gradelist = NULL;
next = NULL;
}
student::student(char tname[]) {
strcpy(name, tname);
average = 0.0;
gradelist = NULL;
next = NULL;
}
student::student(char tname[], grade *tgradelist, float taverage) {
strcpy(name, tname);
average = taverage;
gradelist = tgradelist;
next = NULL;
}
void student::addgrade(float tdata) {
grade *temp = new grade;
temp->data = tdata;
temp->next = gradelist;
if (gradelist == NULL)
temp->next = NULL;
gradelist = temp;
};
void student::avegrades() {
grade *temp = gradelist;
float avetotal = 0;
int count = 0;
if (temp == NULL) {
cout << "\nGrade list empty." << endl;
return;
}
while (temp != NULL) {
avetotal = avetotal + temp->data;
temp = temp->next;
count ++;
}
average = (avetotal/count);
cout << "\nTotal = " << avetotal << endl;
cout << "# of items = " << count << endl;
cout << "Average = " << average << endl;
}
void student::deletegrade(float tdata) {
grade *head;
grade *prev;
grade *curr;
curr = gradelist;
if (curr == NULL) {
cout << "\nGradelist is empty." << endl;
}
else
while(curr != NULL) {
if(curr->data == tdata) {
cout << "\nGrade found." << endl;
prev->next = curr->next;
delete curr;
return;
}
prev = curr;
curr = curr->next;
}
}
void student::printstudent() {
grade *curr;
if (name == NULL)
cout << "No student to print." << endl;
cout << name << " ";
curr = gradelist;
while (curr != NULL) {
cout << curr->data << " ";
curr = curr->next;
}
}
main file:
mainprog.cpp
#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include "class.h"
int main (void) {
char input[80];
float tgradin = 0.0;
cout << "Enter student name: ";
cin >> input;
student t(input);
cout << "\nEnter grade: ";
cin >> tgradin;
t.addgrade(tgradin);
cout << "\nEnter grade: ";
cin >> tgradin;
t.addgrade(tgradin);
cout << "\nEnter grade: ";
cin >> tgradin;
t.addgrade(tgradin);
cout << "\nEnter grade: ";
cin >> tgradin;
t.addgrade(tgradin);
t.avegrades();
cout << "\nDelete grade: ";
cin >> tgradin;
t.deletegrade(tgradin);
t.avegrades();
cin.ignore();
}
-
When you delete the head the prev variabele is not filled yet.
In this case you must point gradelist to the next item before remove the head.
I think it must be something like this (did not test it):
Code:
void student::deletegrade(float tdata)
{
grade *head = NULL;
grade *prev = NULL;
grade *curr = NULL;
curr = gradelist;
if (curr == NULL)
{
cout << "\nGradelist is empty." << endl;
}
else
while(curr != NULL)
{
if(curr->data == tdata)
{
cout << "\nGrade found." << endl;
if(prev == NULL)
gradelist = curr->next;
else
prev->next = curr->next;
delete cur;
return;
}
prev = curr;
curr = curr->next;
}
}
-
I thought that would work, as the explanation totally made sense to me, but for some reason, it still gives me that error. Actually, working on it just now, with a variation on yours, I got it to work. Instead of
Code:
if(prev == NULL)
i used
if(head->data == tdata)
i also changed grade *head to grade *head = gradelist;
This seems to have fixed my problem. I wouldn't have even tried to do what I did without your input. Thanks! :D
-
Err, I just noticed that you had set head, prev and curr to NULL. I tried it again your way, and it works. :)