单链表中的 C++ 读取访问冲突
C++ Read Access Violation in Singly Linked List
我正在编写一个关于创建国家/地区列表的程序,我的代码似乎没有错误,但在调试时,我收到错误:抛出未处理的异常:读取访问冲突 p 为 0xFFFFFFFFFFFFFFFF,在我输入一些内容后值。
任何人都可以给我提示或找出我的错误吗?
#include <cstring>
#include <string>
using namespace std;
这是我的结构省。
struct Province
{
int Code;
string Name;
int Pop;
float Area;
};
struct node
{
struct Province data;
node* next;
};
struct List
{
node* head;
node* tail;
};
void Init(List &l)
{
l.head = NULL;
l.tail = NULL;
}
void add_tail(List& l, node* p)
{
if (l.head == NULL)
{
l.head = p;
l.tail = p;
}
else
{
l.tail->next = p;
l.tail = p;
}
}
我想我在这里创建一个没有初始化值的节点时遇到了一些问题,对吗?
void inputListProvinces(List& l)
{
int n;
cin >> n;
int i = 0;
while(i<n)
{
node* p = new node;
cin >> p->data.Code;
cin.ignore();
getline(cin, p->data.Name);
cin.ignore();
cin >> p->data.Pop;
cin >> p->data.Area;
add_tail(l, p);
i++;
}
}
错误发生在这里,但我不知道如何解决。
void outputListProvinces(List& l)
{
node* p = l.head;
while (p != NULL)
{
cout << p->data.Code << '\t'; /*Unhandled exception thrown: read access violation.
p was 0xFFFFFFFFFFFFFFFF*/
cout << p->data.Name << '\t';
cout << p->data.Pop << '\t';
cout << p->data.Area << '\t';
cout << endl;
p = p->next;
}
}
void outputProvince(node* p)
{
cout << p->data.Code << '\t';
cout << p->data.Name << '\t';
cout << p->data.Pop << '\t';
cout << p->data.Area << '\t';
}
void outputProvincesMore1MillionPop(List& l)
{
node* p = l.head;
while (p != NULL)
{
if (p->data.Pop > 1000)
{
outputProvince(p);
cout << endl;
}
p = p->next;
}
}
node* findProMaxArea(List& l)
{
node* n = l.head;
node* p = l.head;
while (p != NULL)
{
if (p->data.Area > n->data.Area)
{
n = p;
}
p = p->next;
}
return n;
}
int main()
{
List L;
Init(L);
inputListProvinces(L);
cout << "List of provinces:" << endl;
cout << "ID\t|Province\t|Population\t|Area" << endl;
outputListProvinces(L);
cout << "Provinces with a population of more than 1 million:" << endl;
outputProvincesMore1MillionPop(L);
cout << "The largest province:" << endl;
node* p = findProMaxArea(L);
if (p) outputProvince(p);
return 0;
}
错误是 node
从未初始化它的 next
指针。如果将它设置为 NULL
,则只能指望它是 NULL
,并且列表中的最后一个 node
必须是 NULL
,否则程序找不到结尾List
的成员,然后进入 Undefined Behaviour.
的古怪世界
最安全的修复:向 node
添加一个构造函数以确保 next
始终被初始化。
struct node
{
struct Province data;
node* next;
node(node* n = NULL): next(n)
{
}
};
还有其他修复,比如确保 l.tail->next = NULL;
在 inputListProvinces
的末尾,但我认为考虑到控制台 IO 的缓慢性,减少开销真的不值得。
如果你这样做,那么你也应该将 Init
作为构造函数转入 List
:
struct List
{
node* head;
node* tail;
List(): head(NULL), tail(NULL)
{
}
};
这会给您带来一个问题,即 cin.ignore()
消耗了您不想消耗的角色。
旁注:如果您的编译器和目标 C++ 标准版本可用,请将 NULL
替换为 nullptr
。 nullptr
删除了 NULL
被美化 0
.
可能导致的错误
我正在编写一个关于创建国家/地区列表的程序,我的代码似乎没有错误,但在调试时,我收到错误:抛出未处理的异常:读取访问冲突 p 为 0xFFFFFFFFFFFFFFFF,在我输入一些内容后值。 任何人都可以给我提示或找出我的错误吗?
#include <cstring>
#include <string>
using namespace std;
这是我的结构省。
struct Province
{
int Code;
string Name;
int Pop;
float Area;
};
struct node
{
struct Province data;
node* next;
};
struct List
{
node* head;
node* tail;
};
void Init(List &l)
{
l.head = NULL;
l.tail = NULL;
}
void add_tail(List& l, node* p)
{
if (l.head == NULL)
{
l.head = p;
l.tail = p;
}
else
{
l.tail->next = p;
l.tail = p;
}
}
我想我在这里创建一个没有初始化值的节点时遇到了一些问题,对吗?
void inputListProvinces(List& l)
{
int n;
cin >> n;
int i = 0;
while(i<n)
{
node* p = new node;
cin >> p->data.Code;
cin.ignore();
getline(cin, p->data.Name);
cin.ignore();
cin >> p->data.Pop;
cin >> p->data.Area;
add_tail(l, p);
i++;
}
}
错误发生在这里,但我不知道如何解决。
void outputListProvinces(List& l)
{
node* p = l.head;
while (p != NULL)
{
cout << p->data.Code << '\t'; /*Unhandled exception thrown: read access violation.
p was 0xFFFFFFFFFFFFFFFF*/
cout << p->data.Name << '\t';
cout << p->data.Pop << '\t';
cout << p->data.Area << '\t';
cout << endl;
p = p->next;
}
}
void outputProvince(node* p)
{
cout << p->data.Code << '\t';
cout << p->data.Name << '\t';
cout << p->data.Pop << '\t';
cout << p->data.Area << '\t';
}
void outputProvincesMore1MillionPop(List& l)
{
node* p = l.head;
while (p != NULL)
{
if (p->data.Pop > 1000)
{
outputProvince(p);
cout << endl;
}
p = p->next;
}
}
node* findProMaxArea(List& l)
{
node* n = l.head;
node* p = l.head;
while (p != NULL)
{
if (p->data.Area > n->data.Area)
{
n = p;
}
p = p->next;
}
return n;
}
int main()
{
List L;
Init(L);
inputListProvinces(L);
cout << "List of provinces:" << endl;
cout << "ID\t|Province\t|Population\t|Area" << endl;
outputListProvinces(L);
cout << "Provinces with a population of more than 1 million:" << endl;
outputProvincesMore1MillionPop(L);
cout << "The largest province:" << endl;
node* p = findProMaxArea(L);
if (p) outputProvince(p);
return 0;
}
错误是 node
从未初始化它的 next
指针。如果将它设置为 NULL
,则只能指望它是 NULL
,并且列表中的最后一个 node
必须是 NULL
,否则程序找不到结尾List
的成员,然后进入 Undefined Behaviour.
最安全的修复:向 node
添加一个构造函数以确保 next
始终被初始化。
struct node
{
struct Province data;
node* next;
node(node* n = NULL): next(n)
{
}
};
还有其他修复,比如确保 l.tail->next = NULL;
在 inputListProvinces
的末尾,但我认为考虑到控制台 IO 的缓慢性,减少开销真的不值得。
如果你这样做,那么你也应该将 Init
作为构造函数转入 List
:
struct List
{
node* head;
node* tail;
List(): head(NULL), tail(NULL)
{
}
};
这会给您带来一个问题,即 cin.ignore()
消耗了您不想消耗的角色。
旁注:如果您的编译器和目标 C++ 标准版本可用,请将 NULL
替换为 nullptr
。 nullptr
删除了 NULL
被美化 0
.