类成员函数仅在调用一次时起作用

时间:2019-06-21 05:58:13

标签: c++

我已经完成了一个分配,尽管编译器显示了零个错误和警告,但是由于我的类的成员函数之一,我在运行它时遇到了转储堆栈错误。多次调用(循环放置或手动手动调用)时,它将停止工作。

“ 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的可能性。

0 个答案:

没有答案