1

我正在写这段代码,以学习如何正确处理文件和字符串。我已成功管理读取和写入文件的部分内容,但在删除列表中的所有元素的同时堆叠了一段时间。如何从链表中删除正确的元素?

问题是,删除列表中的所有元素后,我试图使用函数printAll,它不会停止,因为它应该发生,我不明白问题在哪里。可能你们中的一些人可以睁开眼睛看看这个bug并帮助解决它。

所以,这个代码是实现一个名为Unit单链表类,其中的变量是字符串的字符串和向量:

class Unit { 
public: 
Unit();//constructor 
void printAllUnits(Unit *head);//-v 
void printUnit(Unit *unit);//-v 
Unit *insert(Unit *head,Unit *element);//-v 
Unit *getNextUnit(Unit **unit);//-v 

Unit *MergeBySN(Unit *leftPtr ,Unit *rightPtr);//-v 
void SplitListBySn(Unit* head,Unit** left, Unit** right);//-v 
int menuSelection(int correct);//prints a menu-v 
void findAndPrintUnitByType(Unit *head, string searchString); 
void findAndPrintUnitBySN(Unit *head, string number); 
void findAndPrintUnitBySNType(Unit *head,string type, string number); 
void findAndPrintUnitByCell(Unit *head, string cell); 
void findAndPrintUnitByUnitLocation(Unit *head, string location); 
void findAndPrintUnitByDate(Unit *head, string date); 
Unit *readFromFile(Unit *head); 
void writeToNewFile(Unit *head); 
void addToFile(Unit *head); 
int checkNumber(string *numberStr); 

Unit *deleteUnit(Unit *unit, string type, string sn);//-v 
void deleteAll(Unit *unit); 

int getChoice(int lower,int upper); 
void SortListBySn(Unit **unit);//-v 
Unit *SortListByType(Unit *unit);//-v 
void mainmenu();//-v 
Unit *subInsert(Unit *head,Unit *element); 
~Unit(); //destructor 

**/*variables*/** 
string Type;//type of unit 
string SN;//serial number of the unit 
int occur;//number of occurences of this serial number during service 
vector<string> Cell;//phisical location 
vector<string> Date;//vactor to hold the dates of changes 
vector<string> unitLocation; 
Unit *next;//link to next unit 
}; 

这里的功能deleteAll和printAll和构造与析构函数一些实现:

正如我在调试器中看见有可以用deleteAll动作之后
/*constructor*/ 
Unit::Unit(){ 
    Type.clear(); 
    SN.clear(); 
    occur=1; 
    Cell.clear(); 
    unitLocation.clear(); 
    next=NULL; 
    Date.clear(); 
} 
/*function to print all elements in the list*/ 
void Unit::printAllUnits(Unit *head){ 
    Unit *tmp; 
    tmp = head; 
    cout<<endl; 
    if (tmp == NULL) 
    { 
    cout<<endl<<"There is no units, Nothing to Print.\n"<<endl; 
    } 
    else 
    { 
    cout<<"  Type  SN  Cell UnitLocations Date "<<endl; 
    cout<<"  ------ ------ ------ -------------- ------ "<<endl; 
    while (tmp != NULL) 
    { 
     printUnit(tmp); 
     tmp = tmp->next; 
    } 
    cout<<endl;cout<<endl; 
    } 
    } 
    /*function to print specific unit*/ 
void Unit::printUnit(Unit *unit){ 
    int i=1; 
    string type; 
    string cell; 
    string sn; 
    string location; 
    string date; 
    if(unit!=NULL){ 
    type=unit->Type; 
    sn=unit->SN; 
    cell=unit->Cell[0]; 
    location=unit->unitLocation[0]; 
    date=unit->Date[0]; 
    cout<<"\t"<<type<<"\t"<<sn<<"\t"<<cell<<"\t\t"<<location<<"\t"<<date<<endl; 
    for(;i < unit->Cell.size();i++){ 
      cell=unit->Cell[i]; 
      location=unit->unitLocation[i]; 
      date=unit->Date[i]; 
      cout<<"\t\t\t"<<cell<<"\t\t"<<location<<"\t"<<date<<endl; 
    } 
     cout<<"Occurency:\t"<<unit->occur<<endl; 
    } 
} 
/*destructor*/ 
Unit::~Unit(){ 
    this->Cell.~vector(); 
    this->Date.~vector(); 
    this->unitLocation.~vector(); 
    this->Type.~basic_string(); 
    this->SN.~basic_string(); 

    } 
/*function to insert element in to list by making a decision after what SN to insert it(kind of  insertion sort)*/ 

Unit *Unit::insert(Unit *head,Unit *element){ 
    Unit *currElement; 
    //*if empty list 
    if(head==NULL){ 
      return element; 
    }//if 
//*if empty 
    if(element->SN < head->SN){ 
      element->next=head; 
      return element; 
    }//if 

    currElement=head; 
    //*compare the serial numbers of elements 

    //*if more 
for(;currElement->next != NULL;currElement=currElement->next){ 
      if(element->SN < currElement->next->SN) 
     break; 
} 

//*equal numbers 
if(currElement->SN==element->SN){//if SN is equal 
    if(currElement->Type.compare(element->Type)==0){//if types are the same 
     currElement->Date.push_back(element->Date[0]); 
     currElement->occur++; 
     currElement->Cell.push_back(element->Cell[0]); 
     currElement->unitLocation.push_back(element->unitLocation[0]); 
    } 
return head; 
} 


//*put new element between current element and it's next elment 
//(if currelement is last then curentelemnt's next ==NULL) 
element->next=currElement->next; 
currElement->next=element; 
return head; 
    } 
    /*main prog*/ 
int main(int argc, char *argv[]){ 
bool flag=0; 
string str; 
string *type;//type of unit (
string *sern;//serial number of the unit 
string *cell;//phisical location 
string *date;//vactor to hold the dates 
string *unitlocation; 
Unit *head1=NULL; 


Unit *tmp=new Unit; 
    /*getting data*/ 
cin>>tmp->Type; 
cin>>tmp->SN; 
cin>>str;tmp->Cell.push_back(str); 
cin>>str;tmp->Date.push_back(str); 
cin>>str;tmp->unitLocation.push_back(str); 
/*inserting in to the list*/ 
    head1=head1->insert(head1,tmp); 
head1->printAllUnits(head1); 
head1->deleteAll(head1); 
head1->printAllUnits(head1); 
return 0; 
} 

的问题时,(VS2008)字段类型和SN有<badptr>并试图打印列表(虽然它是空的)时,程序试图做到这一点,崩溃,虽然我已经检查了NULL或空列表。

所以问题有什么问题的功能deleteALL?我应该如何实现它?

+1

我看你明确调用析构函数。这完全是错误的,因为析构函数也会自动调用。 – UncleBens

+0

函数deleteAll在哪里? – Blazes

+0

请向我们展示您的“deleteAll”的实现。它不在代码中。 –

回答

1

错误很简单 - 您正试图在删除它后打印head1。这是行不通的 - 你不应该调用删除对象的方法。

咋一看刚过,有一些与你的代码的问题:

  • 你不需要任何的构造函数的调用clear的。在任何情况下,初始化时矢量都是空的。
  • 你不应该明确地调用析构函数。他们会自动调用。
  • 您不需要在printAllUnits中制作head的临时副本。
  • 句子中有两个错误:“没有单位,无法打印”。

有很多方法可以实施deleteAll。这里有一个简单的例子:

Unit * Unit::deleteAll(Unit * head) 
{ 
    vector<Unit*> units; 
    while (head) 
    { 
     units.push_back(head); 
     head = head->next; 
    } 
    for (int i(0); i != units.size(); ++i) 
     delete units.at(i); 
    return NULL; 
} 

int main() 
{ 
    // ... 
    head1 = head1->deleteAll(head1); 
    Unit::printAllUnits(head1); 
}