如何解析反向链表的"Unhandled exception thrown: read access violation."?
How to resolve "Unhandled exception thrown: read access violation." for reverse linked list?
我正在使用 Visual Studio Community 2019 在 Windows 10 Pro(64 位)上开发反向链表。我想知道如何解决我遇到的错误,如下所示。我在 class List
的成员函数 reverse()
的 while
循环中遇到以下错误
(*请假设列表已经像连续整数一样准备好,例如 0,1,2,3,4,5)
你能请任何人给我一些建议吗?提前谢谢你。
抛出未处理的异常:读取访问冲突。
当前 是 0xDDDDDDDD。
#include <iostream>
#include <string.h>
#include <vector>
using std::cout;
using std::endl;
template <class Data>
class Node
{
public:
Node* next;
Data data;
};
template <class Data>
class List
{
private:
Node<Data>* head;
Node<Data>* tail;
int count;
public:
//constructor
List()
{
count = 0;
head = nullptr;
tail = nullptr;
}
int size()
{
return count;
}
void msg_empty_list()
{
cout << "The list is not modified since it is empty." << endl;
}
int push_back(Data data)
{
Node<Data>* node = new Node<Data>;
node->data = data;
node->next = nullptr;
if (head == nullptr)
{
head = node;
tail = node;
}
else if (head != nullptr)
{
tail->next = node;
tail = tail->next;
}
count++;
return count;
}
int push_front(Data data)
{
Node<Data>* node = new Node<Data>;
node->data = data;
node->next = nullptr;
if (head == nullptr)
head = node;
else if (head != nullptr)
{
node->next = head;
head = node;
}
count++;
return count;
}
int pop_front(void)
{
if (head == nullptr)
return -1;
else if (head != nullptr)
{
Node<Data>* temp;
temp = head;
head = head->next;
delete temp;
count--;
return count;
}
}
int pop_back(void)
{
if (head == nullptr)
return -1;
else if (head != nullptr)
{
Node<Data>* temp = head;
while (temp->next != tail)
temp = temp->next;
delete tail;
tail = temp;
count--;
return count;
}
}
int remove_at(int index)
{
if (head == nullptr)
return -1;
else if (head != nullptr)
{
cout << "Specified index = " << index << endl;
if (index == 0)
{
pop_front();
}
else if (index == -1)
{
pop_back();
}
Node<Data>* temp = head;
Node<Data>* rmv;
int countIndex = 0;
while (countIndex < index - 1)
{
temp = temp->next;
countIndex++;
}
rmv = temp->next;
temp->next = temp->next->next;
delete rmv;
count--;
return count;
}
}
void reverse()
{
Node<Data>* temp = nullptr;
Node<Data>* prev = nullptr;
Node<Data>* current = head;
while (current != nullptr)
{
temp = current->next; // where I get error "Unhandled exception thrown: read access violation. **current** was 0xDDDDDDDD."
current->next = prev;
prev = current;
current = temp;
}
head = prev;
}
void print()
{
Node<Data>* temp = head;
if (head == nullptr)
return;
for (int i = 0; i < count - 1; i++)
{
cout << temp->data << ", ";
temp = temp->next;
}
cout << temp->data;
}
~List()
{
Node<Data>* temp = head;
while (temp->next != nullptr)
{
temp = temp->next;
delete head;
head = temp;
}
}
};
int main()
{
Node<int> x;
Node<bool> y;
Node<char> n;
List<int> list;
//insert items into list
for (int i = 0; i < 10; i++)
{
list.push_back(i);
}
cout << "Original list[size=" << list.size() << "]: ";
//print the list
list.print();
cout << endl;
// push a node to the beginning of the list
cout << endl << "==> Push a node to the head" << endl;
list.push_front(-1);
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
// pop the head of the list
cout << endl << "==> Pop a node from the head" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.pop_front();
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
/*
// pop the tail of the list
cout << endl << "==> Pop a node from the tail" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.pop_back();
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
*/
// delete the node at the specified index
cout << endl << "==> Delete the node at the specified index" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.remove_at(5);
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
// reverse the list
cout << endl << "==> Reverse the list" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.reverse();
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
return 0;
}
我可以发现您的代码中的一些错误,但让我们专注于 pop_back()
函数:
int pop_back(void)
{
if (head == nullptr)
return -1;
else if (head != nullptr) // 1)
{
Node<Data>* temp = head;
while (temp->next != tail) // 2)
temp = temp->next;
delete tail;
tail = temp; // 3)
count--;
return count;
}
}
- 请不要这样做:
if (a == nullptr) {...} else if (a != nullptr) {...}
是多余的。把第二个 if
放在一边。它让 reader 相信可能存在第三种情况。
- 幸运的是这通常有效,但其他一些方法没有正确更新尾指针,所以这可能永远不会是真的。当列表中只有一个元素时验证
pop_front
方法。其他功能可能也有类似的问题。
- 这是您观察到的实际问题。您没有将新尾部元素的
next
指针设置为空,而是指向现在已删除的尾部。在此行之后插入 tail->next = nullptr
。
我正在使用 Visual Studio Community 2019 在 Windows 10 Pro(64 位)上开发反向链表。我想知道如何解决我遇到的错误,如下所示。我在 class List
reverse()
的 while
循环中遇到以下错误
(*请假设列表已经像连续整数一样准备好,例如 0,1,2,3,4,5) 你能请任何人给我一些建议吗?提前谢谢你。
抛出未处理的异常:读取访问冲突。 当前 是 0xDDDDDDDD。
#include <iostream>
#include <string.h>
#include <vector>
using std::cout;
using std::endl;
template <class Data>
class Node
{
public:
Node* next;
Data data;
};
template <class Data>
class List
{
private:
Node<Data>* head;
Node<Data>* tail;
int count;
public:
//constructor
List()
{
count = 0;
head = nullptr;
tail = nullptr;
}
int size()
{
return count;
}
void msg_empty_list()
{
cout << "The list is not modified since it is empty." << endl;
}
int push_back(Data data)
{
Node<Data>* node = new Node<Data>;
node->data = data;
node->next = nullptr;
if (head == nullptr)
{
head = node;
tail = node;
}
else if (head != nullptr)
{
tail->next = node;
tail = tail->next;
}
count++;
return count;
}
int push_front(Data data)
{
Node<Data>* node = new Node<Data>;
node->data = data;
node->next = nullptr;
if (head == nullptr)
head = node;
else if (head != nullptr)
{
node->next = head;
head = node;
}
count++;
return count;
}
int pop_front(void)
{
if (head == nullptr)
return -1;
else if (head != nullptr)
{
Node<Data>* temp;
temp = head;
head = head->next;
delete temp;
count--;
return count;
}
}
int pop_back(void)
{
if (head == nullptr)
return -1;
else if (head != nullptr)
{
Node<Data>* temp = head;
while (temp->next != tail)
temp = temp->next;
delete tail;
tail = temp;
count--;
return count;
}
}
int remove_at(int index)
{
if (head == nullptr)
return -1;
else if (head != nullptr)
{
cout << "Specified index = " << index << endl;
if (index == 0)
{
pop_front();
}
else if (index == -1)
{
pop_back();
}
Node<Data>* temp = head;
Node<Data>* rmv;
int countIndex = 0;
while (countIndex < index - 1)
{
temp = temp->next;
countIndex++;
}
rmv = temp->next;
temp->next = temp->next->next;
delete rmv;
count--;
return count;
}
}
void reverse()
{
Node<Data>* temp = nullptr;
Node<Data>* prev = nullptr;
Node<Data>* current = head;
while (current != nullptr)
{
temp = current->next; // where I get error "Unhandled exception thrown: read access violation. **current** was 0xDDDDDDDD."
current->next = prev;
prev = current;
current = temp;
}
head = prev;
}
void print()
{
Node<Data>* temp = head;
if (head == nullptr)
return;
for (int i = 0; i < count - 1; i++)
{
cout << temp->data << ", ";
temp = temp->next;
}
cout << temp->data;
}
~List()
{
Node<Data>* temp = head;
while (temp->next != nullptr)
{
temp = temp->next;
delete head;
head = temp;
}
}
};
int main()
{
Node<int> x;
Node<bool> y;
Node<char> n;
List<int> list;
//insert items into list
for (int i = 0; i < 10; i++)
{
list.push_back(i);
}
cout << "Original list[size=" << list.size() << "]: ";
//print the list
list.print();
cout << endl;
// push a node to the beginning of the list
cout << endl << "==> Push a node to the head" << endl;
list.push_front(-1);
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
// pop the head of the list
cout << endl << "==> Pop a node from the head" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.pop_front();
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
/*
// pop the tail of the list
cout << endl << "==> Pop a node from the tail" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.pop_back();
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
*/
// delete the node at the specified index
cout << endl << "==> Delete the node at the specified index" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.remove_at(5);
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
// reverse the list
cout << endl << "==> Reverse the list" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.reverse();
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
return 0;
}
我可以发现您的代码中的一些错误,但让我们专注于 pop_back()
函数:
int pop_back(void)
{
if (head == nullptr)
return -1;
else if (head != nullptr) // 1)
{
Node<Data>* temp = head;
while (temp->next != tail) // 2)
temp = temp->next;
delete tail;
tail = temp; // 3)
count--;
return count;
}
}
- 请不要这样做:
if (a == nullptr) {...} else if (a != nullptr) {...}
是多余的。把第二个if
放在一边。它让 reader 相信可能存在第三种情况。 - 幸运的是这通常有效,但其他一些方法没有正确更新尾指针,所以这可能永远不会是真的。当列表中只有一个元素时验证
pop_front
方法。其他功能可能也有类似的问题。 - 这是您观察到的实际问题。您没有将新尾部元素的
next
指针设置为空,而是指向现在已删除的尾部。在此行之后插入tail->next = nullptr
。