Why is an exception thrown whilst removing a node from a doubly linked list?

Hello,

I have written a function to relink and delete a node from a doubly linked list data structure. I keep getting exceptions thrown in relation to failing to access memory.

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
#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

//const int MAXRECS = 3; // maximum number of records

struct TeleType
{
	string name;
	string phoneNo;
	TeleType *nextaddr;
	TeleType *prevaddr;
};

void populate(TeleType *); // function prototype needed by main()
void display(TeleType *); // function prototype needed by main()
void remove_head(TeleType *); //function prototype for main()
void remove_current(TeleType *); //function prototype for main()
void remove_tail(TeleType *); //function prototype for main()
void make_list();

TeleType head, tail, current;

TeleType *phead = &head;
TeleType *pcurrent = &current;
TeleType *ptail = &tail; // 3 pointers to structures of
						 // type TeleType
						 // get a pointer to the first structure in the list

int main()
{
	int i;
	cout << "The list will now be made" << endl;

	make_list();

	cout << "\nThe list consists of the following records:\n";

	display(phead); // display the structures

	cout << "Which record would you like to remove?" << endl;
	cout << "select 1 if you want to remove the head, 2 for the middle and 3 for the tail" << endl;

	cin >> i;
	switch (i)
	{
		case 1:
			remove_head(phead);
			display(pcurrent);
		case 2: 
			remove_current(pcurrent);
			display(phead);
		case 3:
			remove_tail(pcurrent);
		break;
	}

	system("pause");

	return 0;
}

void make_list()
{
	//Input values for head structure
	populate(phead);
	//Assign nextaddr pointer to current
	head.nextaddr = pcurrent;
	//Input values for current structure
	populate(pcurrent);
	//Assign current structure's newaddr and preaddr
	current.prevaddr = phead;
	current.nextaddr = ptail;
	//Input values for tail
	populate(ptail);
	//Assign prevaddr pointer
	tail.prevaddr = pcurrent;
	//assign newaddr pointer as null to tail structure
	tail.nextaddr = NULL;
	// assign prevaddr pointer as current pointer  for tail structure
	return;
}

// input a name and phone number
void populate(TeleType *record) // record is a pointer to a
{ // structure of type TeleType

	cout << "Enter a name: ";
	getline(cin, record->name);

	cout << "Enter the phone number: ";
	getline(cin, record->phoneNo);

	return;
}

void display(TeleType *contents) // contents is a pointer to a
{ // structure of type TeleType

	while (contents != NULL) // display until end of linked list
	{
		cout << endl << setiosflags(ios::left)
			<< setw(30) << contents->name
			<< setw(20) << contents->phoneNo
			<< setw(20) << contents->prevaddr
			<< setw(20) << contents->nextaddr;
		contents = contents->nextaddr;
	}
	cout << endl;

	return;
}

void remove_head(TeleType *record)
{
	current.prevaddr = NULL;
	current.nextaddr = ptail;

	tail.prevaddr = pcurrent;
	tail.nextaddr = NULL;

	delete record;

	return;
}

void remove_current(TeleType *record)
{
	head.nextaddr = ptail;

	tail.prevaddr = phead;
	tail.nextaddr = NULL;

	delete record;

	return;
}

void remove_tail(TeleType *record)
{

}
You should only delete a variable created with new.
Your pointer is not pointing to dynamic memory, so it should not be deleted with new.

If you want to use delete, allocate phead/pcurrent/ptail with new. Otherwise, just remove the delete calls.
Last edited on
foo.cpp: In function ‘int main()’:
foo.cpp:51:11: warning: this statement may fall through [-Wimplicit-fallthrough=]
foo.cpp:54:11: warning: this statement may fall through [-Wimplicit-fallthrough=]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
	switch (i)
	{
		case 1:
			remove_head(phead);
			display(pcurrent);
			break; //<--- add this
		case 2: 
			remove_current(pcurrent);
			display(phead);
			break; //<--- add this
		case 3:
			remove_tail(pcurrent);
		break;
	}
without the breaks, the code keeps executing.

if you keep having issues, provide an example input.
Hello,

Since tidying up the switch statement in the main, I have been able to get it working.

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
#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

struct TeleType
{
	string name;
	string phoneNo;
	TeleType *nextaddr;
	TeleType *prevaddr;
};

void populate(TeleType *); // function prototype needed by main()
void display(TeleType *); // function prototype needed by main()
void remove_head(TeleType *); //function prototype for main()
void remove_current(TeleType *); //function prototype for main()
void remove_tail(TeleType *); //function prototype for main()
void make_list();
void insert(TeleType *);

TeleType head, tail, current;

TeleType *phead = &head;
TeleType *pcurrent = &current;
TeleType *ptail = &tail; // 3 pointers to structures of
						 // type TeleType
						 // get a pointer to the first structure in the list

int main()
{
	int i;
	cout << "The list will now be made" << endl;

	make_list();

	cout << "\nThe list consists of the following records:\n";

	display(phead); // display the structures

	cout << "Which record would you like to remove?" << endl;
	cout << "select 1 if you want to remove the head, 2 for the middle and 3 for the tail, 4 to insert a new record" << endl;

	cin >> i;

	cout << endl;

	switch (i)
	{
	case 1:
		remove_head(phead);
		display(pcurrent);
		break;
	case 2:
		remove_current(pcurrent);
		display(phead);
		break;
	case 3:
		remove_tail(pcurrent);
		display(phead);
		break;
	case 4:
		insert(ptail);
		display(phead);
		break;
	}

	system("pause");

	return 0;
}

void make_list()
{
	//Input values for head structure
	populate(phead);
	//Assign nextaddr pointer to current
	head.nextaddr = pcurrent;
	//Input values for current structure
	populate(pcurrent);
	//Assign current structure's newaddr and preaddr
	current.prevaddr = phead;
	current.nextaddr = ptail;
	//Input values for tail
	populate(ptail);
	//Assign prevaddr pointer
	tail.prevaddr = pcurrent;
	//assign newaddr pointer as null to tail structure
	tail.nextaddr = NULL;
	// assign prevaddr pointer as current pointer  for tail structure
	return;
}

// input a name and phone number
void populate(TeleType *record) // record is a pointer to a
{ // structure of type TeleType

	cout << "Enter a name: " << endl;
	getline(cin, record->name);

	cout << "Enter the phone number: ";
	getline(cin, record->phoneNo);

	return;
}

void display(TeleType *contents) // contents is a pointer to a
{ // structure of type TeleType

	while (contents != NULL) // display until end of linked list
	{
		cout << endl << setiosflags(ios::left)
			<< setw(30) << contents->name
			<< setw(20) << contents->phoneNo
			<< setw(20) << contents->prevaddr
			<< setw(20) << contents->nextaddr;
		contents = contents->nextaddr;
	}
	cout << endl;

	return;
}

void remove_head(TeleType *record)
{
	current.prevaddr = NULL;
	current.nextaddr = ptail;

	tail.prevaddr = pcurrent;
	tail.nextaddr = NULL;

	return;
}

void remove_current(TeleType *record)
{
	head.nextaddr = ptail;

	tail.prevaddr = phead;
	tail.nextaddr = NULL;

	return;
}

void remove_tail(TeleType *record)
{
	current.nextaddr = NULL;
	current.prevaddr = phead;

	return;
}

void insert(TeleType *record)
{
	TeleType *ptr_new_record = new TeleType; //create a new structure, return an address and assign it to a ptr
												//new record.

	record->nextaddr = ptr_new_record; //change the nextaddr pointer to point to the new record

	ptr_new_record->nextaddr = NULL; //assign new null pointer
	ptr_new_record->prevaddr = ptail; //assign new pointer of new record to point to the the old tail structure.

	populate(ptr_new_record); //call populate function to fill in data members of the structure.

	return;
}
Topic archived. No new replies allowed.