如何从链表中删除正确的元素?

时间:2011-08-10 15:03:47

标签: c++ list memory-management linked-list dynamic-memory-allocation

我正在编写此代码,以便我自己学习如何正确处理文件和字符串。我已成功处理了读取和写入文件的部分,但在删除列表中的所有元素时堆叠了一段时间。

问题是,在删除列表中的所有元素后,我正在尝试使用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以及带有析构函数的构造函数:

 /*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;
 }

在进行deleteAll操作后出现问题,正如我在调试器(VS2008)字段中看到的Type和SN有<badptr>,当尝试打印列表时(虽然它是空的),程序会尝试执行此操作,虽然我已经检查了NULL或空列表,但崩溃了。

那么问题 deleteALL 的功能有什么问题?我该如何实施呢?

1 个答案:

答案 0 :(得分:2)

错误很简单 - 您在删除后尝试打印head1。这不起作用 - 你不应该在删除的对象上调用方法。

快速查看后,您的代码存在许多问题:

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

有多种方法可以实现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);
}