我正在使用类编写程序,但遇到了一个奇怪的错误,但只是偶尔。我相信该错误是由堆栈溢出或我的指针之一弄乱引起的。当我运行程序时,它将循环几次,并将我的记录类添加到列表中,但是一旦到达第三项,我就会收到SIGSEGV Segmentation Fault错误。当我使用GDB并逐步执行程序并尝试打印'current-> id'的值时,它说“无法访问地址0xe0的内存”。这是我遇到麻烦的代码部分,应该将其复制到另一个列表中。

list&list :: operator=( const list& list1 )
{
    rec * current = NULL;
    current = list1.first;

    rec temprec;
    char tempid[15];
    char tempfirst[15];
    char templast[15];
    int answersin[10];

    while( current -> id != NULL)
    {
        //Printing Data to follow program easier
        cout << endl;
        cout << tempid;
        cout << endl;
        cout << current -> id;  //Receive error on this line
        cout << endl;

        strcpy(tempid, current -> id);
        strcpy(tempfirst, current -> firstname);
        strcpy(templast, current -> lastname);
        for(int i=0; i<10; i++)
        {
            answersin[i]=current -> a[i];
        }
        temprec.SetData( tempid, tempfirst, templast, answersin );
        if ( AddItem( temprec ) )
        {
            cout << "Success.";
        }
        else
        {
            cout << "Failed.";
        }
        current = current -> next;
    }

} // End Operator =


如果是堆栈溢出,那么解决该问题的最佳方法是什么?我不确定应该将什么存储在堆vs堆栈中。我检查了指针,它们对我来说似乎还不错,但我可能错了。任何帮助是极大的赞赏!

编辑1:我发现我的问题是我传递的列表不是以null结尾的。如果我在主程序中列出了列表,那没有问题,但是当我在此函数中列出列表时,它就会搞砸了(仍然只是有时候,我只相信更大的列表)。该功能应该将所选人员的答案与其他人的答案进行比较,并列出包含最匹配记录的列表。

    list list :: BestMatch ( char *IDinput )
{
    rec * ptr;        // pointer for traversing
    ptr = first;      // set pointer to the beginning of the list
    rec * CompPtr;    // pointer for traversing to compare answers
    CompPtr = first;  // set compare pointer to the beginning of the list
    int compare = 0;  // variable to compare strings
    int score = 0;
    int currentMax = 0;
    list returnList;

    while (ptr)  // loops through until the end of the list
    {
        compare = strcmp( IDinput, ptr -> id );  // compare id to be Matched to the id that ptr points to
        if ( compare == 0 )  // "if id to be Matched matches an id in the list"
        {
            break;  // break from loop
        }
        ptr = ptr -> next;  // go to the next node in the list to be checked
    }
    if (!ptr) // If ptr = NULL, meaning the end of the list was reached
    {
        cout << "ID for Match Not found." << endl;
        return returnList;
    }
    while (CompPtr) // loops through until all the answers are compared
    {
        score = ComputeScore ( ptr, CompPtr ); // Compares answers from id to be Matched to current node in the list
        if ( score == 0)
        {
            ; // Do nothing
        }
        else if ( score > currentMax )
        {
            returnList.DeleteList();          // Delete all other items in list because new score is greater than all of them
            if ( returnList.AddItem( *CompPtr ) )  // Add new item with highest score to the list
            {
                cout << "\nSuccess!\n";
            }
            else
            {
                cout << "\nMatch.\n";
            }
            currentMax = score;             // Make the new current max be equal to the score of the new greatest match
        }
        else if ( score == currentMax )
        {
            returnList.AddItem( *CompPtr );  // Simply add to list due to same score
        }
        else //(score < currentMax)
        {
            ; //Do nothing.
        }
        CompPtr = CompPtr -> next; // advance to the next node to be compared
    }
    ptr = NULL;
    CompPtr = NULL;
    returnList.PrintList( 0 );
    return returnList;
} // End BestMatch


使用的ComputeScore函数:

    int list :: ComputeScore ( rec* Input, rec* Compare)
{
    int ReturnScore =0;
    int compare =0;

    // Prevents comparing to self
    compare = strcmp(Input -> id, Compare -> id);
    if (compare == 0)  // id match found
    {
        return 0; // cannot match with self
    }

    // Check to see if gender is appropriate for match
    if ( Input -> a[9] != Compare -> a[0] )
    {
        return 0;
    }
    else
    {
        ;
    }

    // Check to see if school year is appropriate for class
    if ( Input -> a[7] == 1 && Compare -> a[1] != 1 )
    {
        return 0;
    }
    else if ( Input -> a[7] == 2 && Compare -> a[1] != 2 )
    {
        return 0;
    }
    else if ( Input -> a[7] == 3 && Compare -> a[1] != 3 )
    {
        return 0;
    }
    else if ( Input -> a[8] == 4 && Compare -> a[2] != 4 )
    {
        return 0;
    }
    else
    {
        ; // Do nothing & Continue
    }

    // Compare other answers
    if ( Input -> a[2] == Compare -> a[2] )
    {
        ReturnScore = ReturnScore + 1;
    }

    if ( Input -> a[3] == Compare -> a[3] )
    {
        ReturnScore = ReturnScore + 1;
    }

    if ( Input -> a[4] == Compare -> a[4] )
    {
        ReturnScore = ReturnScore + 1;
    }

    if ( Input -> a[5] == Compare -> a[5] )
    {
        ReturnScore = ReturnScore + 1;
    }

    if ( Input -> a[6] == Compare -> a[6] )
    {
        ReturnScore = ReturnScore + 1;
    }

    if ( Input -> a[8] == Compare -> a[8] )
    {
        ReturnScore = ReturnScore + 1;
    }

    return ReturnScore;

} // End ComputeScore


以及一些其他信息可能会对我的头文件有所帮助:

class rec
{
public:
    rec ( char * i, char * fn, char * ln, int * ans );  //constructor
    rec ( void );                                       //default constructor
    rec& operator=( const rec& r );
    rec ( const rec& r );                               //copy constructor
    ~rec( );
    void SetData( char * id_in, char * fn, char * ln, int * ans_in );
    char ReturnID ( const rec& r );
    void Print( );
    friend class list;
private:
    char id[15];
    char firstname[15];
    char lastname[15];
    int a[10];
    rec* prev;
    rec* next;
};

class list
{
public:
    list ( void );                          //default constructor
    list& operator=( const list& list1 );   //deep copy one list to another
    int AddItem ( const rec& r );
    int DeleteItem ( char* delid );
    void PrintList ( int order );
    int Count(char *FileName);
    void DeleteList ( );
    int ReadData ( char* file1, char* file2 );
    int WriteData ( char* wfile1, char* wfile2);
    int ComputeScore ( rec* Input, rec* Compare);
    list BestMatch ( char* IDinput );
    list TopTen ( char* IDinput );
private:
    rec * first;
    rec * last;
};

最佳答案

对于列表中的最后一个元素,其next将是NULL,因此在current = current -> next;之后,当前元素将是NULL,并且您尚未通过current->id对其进行取消引用。所以我建议在while循环中添加此检查:

while(current && (current -> id != NULL)) {
    ...
}

关于c++ - 堆栈溢出或指针错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36818898/

10-13 08:13
查看更多