我正在利用类制作一个程序,但遇到了一个奇怪的错误,但只是偶尔。我相信错误是由堆栈溢出或我的一个指针搞砸引起的。当我运行我的程序时,它会循环几次并将我的记录类添加到列表中,但是一旦它到达第 3 项,我就会收到 SIGSEGV 分段错误错误。当我使用 GDB 并逐步执行我的程序并尝试打印"当前 -> 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 =
如果是堆栈溢出,修复它的最佳方法是什么?我不确定应该在堆与堆栈中存储什么。我已经检查了我的指针,它们对我来说似乎没问题,但我可能是错的。任何帮助将不胜感激!
编辑 1:我发现我的问题是我传入的列表不是空终止的。如果我在我的主程序中制作一个列表,我没有问题,但是当我在这个函数中制作我的列表时,它会搞砸(仍然只是有时,我相信只在更大的列表中)。此功能应该将所选人员的答案与另一个人的答案进行比较,并创建一个包含匹配次数最多的记录的列表。
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
使用的计算分数函数:
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)) {
...
}