Deleting node from Linked List not working

I've been stuck on this project for class for 3 days. This is my first linked list. I'm referencing all kinds of examples and tutorials and can't figure out where I've gone wrong. Can someone tell me why I get runtime errors when trying to delete a node?

List.CreateList() and List.PrintList() work great, but when using a loop to look for nodes whose members meet the deletion requirements, I get an error. Sometimes on the loop's line and sometimes on the delete function's line.

Please, tell me what I'm doing wrong here?

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
//a Food struct stores info for a food
struct Food
{
string name, group;
float cal, per;
Food* next;
};
typedef Food* FoodPtr;


////////////////////////       CLASS DEFINITION       /////////////////////////
//LList manages the linked list
class LList
{
private:

public:

FoodPtr head, tail, index;

//function prototypes go here
LList();
~LList();
void CreateList();
FoodPtr ReadFood(ifstream &inFile);
void PrintList();
FoodPtr PrevNode(FoodPtr index);
void Forward();
void Backward();
void DelNode(FoodPtr index);

//function prototypes end here
};

////////////////////////       FUNCTION DEFINITIONS       /////////////////////////
//function definitions go here

LList::LList()
{
    head=tail=index=NULL;
}

LList::~LList()
{
    FoodPtr temp, deltor;
    temp=deltor=head;

    while (temp!=NULL)
    {
        temp=temp->next;
        delete deltor;
        deltor=temp;
    }
}

void LList::CreateList()
{
    //testing new code
    ifstream inFile;
    inFile.open("file.txt");

    if (inFile.fail())
    {
        cout << "Fail\n";
    }

    FoodPtr temp;

    while ((temp=ReadFood(inFile)))
    {
        //add Food to list
        if (head==NULL)
        {
            //creates head of list
            head=temp;
            //node is only one in the list, is both head and tail right now
            tail=temp;
        }
        else
        {
            //current Food, tail, now references new Food
            tail->next=temp;
            //new food becomes tail, referenced by previous Food
            tail=temp;
        }
    }

    //end of list
    index=head;
    tail->next=NULL;
    //always close the stream
    inFile.close();
}

FoodPtr LList::ReadFood(ifstream &inFile)
{
    FoodPtr temp=NULL;
    //temp values
    string tName, tGroup;
    float tCal, tPer;

    if (inFile >> tName >> tGroup >> tCal >> tPer)
    {
        temp=new Food;
        //store info in created object
        temp->name=tName;
        temp->group=tGroup;
        temp->cal=tCal;
        temp->per=tPer;
    }
    return temp;

}

void LList::PrintList()
{
    FoodPtr temp;


    cout << "============================================================================\n";
    cout << "Food Name" << setw(20) << "Food Group" << setw(20) << "Calories" << setw(20)
     << "Daily Percentage" << endl;
     cout << "===========================================================================\n";

    for (temp=head;temp!=NULL;temp=temp->next)
    {
        cout << temp->name << setw(20) << temp->group << setw(20) << temp->cal << setw(20)
        << temp->per << endl;
    }
}

FoodPtr LList::PrevNode(FoodPtr index)
{
    FoodPtr temp=head;
    if (index==head) //no previous node, return head
    {
        return head;
    }
    while (temp->next!=index)
    {
        temp=temp->next;
    }
    return temp;
}

void LList::Forward()
{
    if (index->next!=NULL)
    {
        index=index->next;
    }
}

void LList::Backward()
{
    if (index!=head)
    {
        index=PrevNode(index);
    }
}

void LList::DelNode(FoodPtr index)
{
    FoodPtr deltor=index;

    if (index==head) //delete the head
    {
        head=head->next;
        delete deltor;
    }
    else if (index==tail) //delete the tail
    {
        tail=PrevNode(index);
        tail->next=NULL;
        delete deltor;
    }
    else //delete a middle node
    {
        index=PrevNode(index);
        index->next=deltor->next;
        delete deltor;
    }
    index=head;
}

//function definitions end here

////////////////////////       MAIN       /////////////////////////
int main()
{
    LList List;
    FoodPtr head, tail, index;
    int calLimit;

    List.CreateList();
    List.PrintList();

    cout << "\n\n\n\n";
    cout << "set cal limit?:";
    cin >> calLimit;

    while (index!=NULL)
    {
        if (index->cal>calLimit)
        {
            List.DelNode(index);
        }
        index=index->next;
    }

    List.PrintList();

    return 0;
}
I know nothing of this but perhaps this can help you out:

http://www.cs.bu.edu/teaching/c/linked-list/delete/
In your loop, your DelNode will be deleting index. You then try to access index->next on line 208. Naturally, that fails. You should have DelNode return a FoodPtr to the next valid node.
List.DelNode(index) passes index to the function, and at the end of the function, index is always assigned the value of "head", starting the loop over from the beginning of the linked list. So index->next on line 208 should be valid.
closed account (D80DSL3A)
You are passing index to DelNode() by value, not by reference. Assignments made to index in the function do not affect the value of index in main(). Zhuge is right.
closed account (z05DSL3A)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class LList
{
//...
public:
FoodPtr head, tail, index;
//...
};

int main()
{
    //...
    FoodPtr head, tail, index;
    //...

    while (index!=NULL)   // What index do you think you are using and is it initialised?
    {
        if (index->cal>calLimit)
        {
            List.DelNode(index);
        }
        index=index->next;
    }
    //...
}
toexii:

Thanks for the link. I had seen that and was using it as a reference, but still couldn't wrap my head around it.



Zhuge and Fun2Code:

That was it! I was passing by val instead of by ref. Also, after declaring the FoodPtrs head, tail and index in Main(), I didn't initialize them because I thought they were getting the values from the class.

So I initialized them, after using List.CreateList() and List.PrintList(), to the head, tail, index values in List. Then I changed DelNode to pass index by ref and everything worked exactly as intended.

Thanks so much for the help!
Topic archived. No new replies allowed.