Reputation: 63
I was writing a program to learn doubly linked lists. The problem I can't seem to debug is that the debugger gives me a write access violation and states that either the prevNode->next or nextNode->prev are pointing to a null. This happens as soon as you try to delete a node from nth position. I have removed some parts of the code for this post to make it shorter and easier to read, so some variables may seem unused.
The part that the debugger usually stops at is the last line before you delete the node:
nextNode = nodePtr->next;
prevNode = nodePtr->prev;
nextNode->prev = prevNode;
prevNode->next = nextNode;
delete(nodePtr);
I know for deleting nodes in the beginning and end of a list will require different code (if statement) to make sure prevNode->next and nextNode->prev are not set to a node that does not exist. The problem is that it's giving me those errors even when I'm trying to delete a node that isn't in the beginning or end of a list.
Any help or a push in the right direction would be much appreciated!
#include <iostream>
using namespace std;
int main() {
struct ListNode {
int value;
ListNode *next;
ListNode *prev;
};
ListNode *head = nullptr;
ListNode *newNode = nullptr;
ListNode *nodePtr = nullptr;
ListNode *prevPtr = nullptr;
ListNode *nextNode = nullptr;
ListNode *prevNode = nullptr;
char ch = 'q';
int val;
int pos;
do
{
cout << "h-delete from position" << endl;
cout << "i-insert" << endl;
cout << "p-print" << endl;
cout << "q-quit" << endl;
cin >> ch;
switch (ch) {
case 'i':
cout << "inserting ... \n";
cout << "Enter an integer: ";
cin >> val;
newNode = new ListNode;
newNode->value = val;
newNode->next = nullptr;
if (head == nullptr) {
head = newNode;
}
else {
nodePtr = head;
prevPtr = nullptr;
while (nodePtr != nullptr && nodePtr->value < newNode->value) {
prevPtr = nodePtr;
nodePtr = nodePtr->next;
}
if (prevPtr == nullptr) {
head = newNode;
newNode->next = nodePtr;
}
else {
prevPtr->next = newNode;
newNode->next = nodePtr;
}
}
break;
case 'p':
cout << "printing ... \n";
nodePtr = head;
while (nodePtr != nullptr) {
cout << "elem: " << nodePtr->value << endl;
nodePtr = nodePtr->next;
}
break;
case 'h':
//FIX
int findVal;
cin >> findVal;
nodePtr = head;
while (nodePtr->value != findVal) {
nodePtr = nodePtr->next;
}
nextNode = nodePtr->next;
prevNode = nodePtr->prev;
nextNode->prev = prevNode;
prevNode->next = nextNode;
delete(nodePtr);
break;
case 'q':
cout << "quitting ... \n";
nodePtr = head;
while (nodePtr != nullptr) {
nextNode = nodePtr->next;
cout << "deleting ... " << nodePtr->value << endl;
delete nodePtr;
nodePtr = nextNode;
}
break;
default:
system("CLS");
cout << "Invalid character -- Please try again!" << endl;
break;
}
} while (ch != 'q');
system("pause");
return 0;
}
Upvotes: 0
Views: 684
Reputation: 2623
Well in h
case, if you enter a value that does not exist, you would try to use the object at null address.
Also, if you delete the first node (the head), it won't get updated so any other operation after that what can fails as you use a destroyed object and this is undefined behavior.
Upvotes: 0
Reputation: 8514
This line will fail:
prevNode = nodePtr->prev;
.....
prevNode->next = nextNode;
because you don't give prev
a value when you insert a node. So prevNode
will always be nullptr
Stepping through line by line in the debugger will help you find these type of bugs.
Upvotes: 1