我已经完成了一个分配,尽管编译器显示了零个错误和警告,但是由于我的类的成员函数之一,我在运行它时遇到了转储堆栈错误。多次调用(循环放置或手动手动调用)时,它将停止工作。
“ FlowList”类从文本文件创建链接列表,并按流值的升序显示数据。
这是文本文件的内容:
YEAR FLOW (in billion cubic metres)
1970 100.34
2000 110.22
1999 110.99
1945 145.66
1922 192.99
1971 209.99
1900 220.11
2001 231.44
1989 234.98
1946 300.99
这是类“ Flowlist”的头文件的一部分:
struct ListItem {
int year;
double flow;
};
struct Node {
ListItem item;
Node *next;
};
class FlowList {
public:
FlowList();
FlowList (const FlowList& source);
FlowList& operator = (const FlowList& rhs);
~FlowList();
void reset();
void insert(const int y, const int f);
//other class member functions
private:
Node *headM;
Node *cursorM; //This must always either point to the first item in
//the linked list or point to NULL.
//other code
};
FlowList的成员函数定义:
FlowList::FlowList():headM(NULL), cursorM(NULL){}
void FlowList::reset(){
cursorM = headM;
}
这是FlowList类的插入函数,该函数在多次调用后将停止工作:
void FlowList::insert(const ListItem& itemA){
Node *newNode = new Node;
newNode->item = itemA;
if (headM == NULL){
newNode->next = headM;
headM = newNode;
}
else if (itemA.flow <= headM->item.flow && itemA.year != headM->item.year){
newNode->next = headM;
headM = newNode;
}
else {
reset();
Node *after = headM->next;
while(after != NULL && itemA.flow > after->item.flow){
cursorM = after;
after = after->next;
}
if (itemA.year != after->item.year){
newNode->next = after;
cursorM->next = newNode;
}
else delete newNode;
}
cursorM = NULL;
}
头文件“ hydro”用于显示,读取和写入文本文件的数据。
“水电”头文件的一部分:
#include "list.h"
int readData(FlowList&); //calls insert()
//other code
readData的函数定义:
int readData (FlowList& f){
ifstream records;
records.open("flow.txt");
if (records.fail()){
cout << "\nERROR. File cannot be opened.\nProgram terminated." << endl;
exit(1);
}
ListItem data;
while (!records.eof()){
records >> data.year >> data.flow;
f.insert(data); //This is where the error occurs.
} //insert only works when called once.
records.close();
return f.count(); //This returns the number of nodes in the
//filled up linked list.
}
这是控制台上显示的转储堆栈错误:
Exception: STATUS_ACCESS_VIOLATION at rip=00100401DEF
rax=0000000000000000 rbx=00000000FFFFCC00 rcx=00000000FFFFCB80
rdx=00000000000007D0 rsi=000000018027FB40 rdi=0000000000008000
r8 =0000000000000000 r9 =000000018030B0A8 r10=0000000100000000
r11=00000003CA2E85FC r12=0000000180248C20 r13=00000000FFFFCC76
r14=0000000000000000 r15=00000000FFFFCC76
rbp=00000000FFFFC900 rsp=00000000FFFFC8C0
program=C:\Users\*******\eclipse-workspace\Lab 5 Exercise C v1\Debug\Lab 5 Exercise C v1.exe, pid 1184, thread main
cs=0033 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame Function Args
000FFFFC900 00100401DEF (001000007D0, 0000000006E, 000FFFFD680, 006000007D0)
000FFFFC990 001004011FB (0018019814C, 000FFFFCC76, 00180333F78, 0018027FB40)
000FFFFCBD0 00100402250 (00000000020, 70700000006FF00, 0018004A7AA, 000FFFFCCD0)
000FFFFCCD0 0018004A816 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 00180048353 (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFFFF0 00180048404 (00000000000, 00000000000, 00000000000, 00000000000)
End of stack trace
任何帮助将不胜感激!
编辑: 基于建议学习如何调试的知识,我更改了插入函数的代码以使其正常工作。
void FlowList::insert(const ListItem& itemA){
Node *newNode = new Node;
newNode->item = itemA;
newNode->next = NULL; //Initialized the "next" pointer
if (headM == NULL){
newNode->next = headM;
headM = newNode;
}
else if (itemA.flow <= headM->item.flow && itemA.year != headM->item.year){
newNode->next = headM;
headM = newNode;
}
else {
reset();
Node *after = headM->next;
while(after != NULL && itemA.flow > after->item.flow){
cursorM = after;
after = after->next;
}
//-----------These are the changes------------
if (after == NULL && itemA.year != cursorM->item.year){
newNode->next = NULL;
cursorM->next = newNode;
}
else if (itemA.flow <= after->item.flow && itemA.year != after->item.year){
newNode->next = after;
cursorM->next = newNode;
}
//--------------------------------------------
else delete newNode;
}
cursorM = NULL;
}
分段错误来自itemA.year != after->item.year
比较,在该比较中我没有考虑指针“之后”将指向NULL的可能性。