如果先前的输入与当前输入相同,为什么cin的行为会有所不同?

时间:2015-04-07 12:02:13

标签: c++

#include<iostream>
using namespace std;

class node{
int data;
node *prev;
node *next;
public:
    node(int n){
        data=n;
        prev=NULL;
        next=NULL;      
    }
    void insert_end(node**,node**);
    void insert_beg(node**,node**);
    void insert_after(node**,node**);
    void delete_end(node**,node**);
    void delete_start(node**,node**);
    void display(node**,node**);
    node* find(node**,node**,int n);
};

void node::insert_end(node **start,node **end){
    int n;
    if(*start!=NULL){
        cout<<"Enter number \n";
        cin>>n;
        node *obj=new node(n);
        (*end)->next=obj;
        obj->prev=*end;
        *end=(*end)->next;
    }
    else{
        cout<<"Enter number \n";
        cin>>n;
        node *obj=new node(n);
        *start=obj;
        *end=obj;
    } 
}

void node::insert_beg(node **start,node **end){
    int n;
    if(*start!=NULL){
        cout<<"Enter number \n";
        cin>>n;
        node *obj=new node(n);
        (*start)->prev=obj;
        obj->next=*start;
        *start=obj;
    }
    else{
        cout<<"Enter number \n";
        cin>>n;
        node *obj=new node(n);
        *start=obj;
        *end=obj;
    } 
}

void node::insert_after(node **start,node **end){
    int n,nn;
    if(*start!=NULL){
        cout<<"Enter number \n";
        cin>>n;
        cout<<"Enter number after which element is to be inserted\n";
        cin>>nn;
        node *pos=find(start,end,nn);
        if(pos==NULL){
            cout<<"No such element "<<nn<<endl;
        }
        else{
            node *obj=new node(n);
            obj->prev=pos;
            obj->next=pos->next;
            pos->next->prev=obj;
            pos->next=obj;
        }
    }
    else{
        cout<<"Enter number \n";
        cin>>n;
        cin.clear();
        cin.ignore(10000,'\n');
        node *obj=new node(n);
        *start=obj;
        *end=obj;
    } 
}

void node::display(node** start,node** end){
    if(*start==NULL)cout<<"Empty list\n";
    else{
        node *temp=*start;
        cout<<"List is :"<<endl;
        while(temp!=NULL){          
            cout<<"\n"<<(temp)->data;
            temp=(temp)->next;
        }
    }
}

void node::delete_end(node** start,node** end){
    if(*start==NULL)cout<<"Empty list";
    else{
        node *temp=*end;
        temp->prev->next=temp->next;
        *end=(*end)->prev;
    }
}

void node::delete_start(node** start,node** end){
    if(*start==NULL)cout<<"Empty list";
    else{
        node *temp=*start;
        temp->next->prev=NULL;
        *start=(*start)->next;
    }
}

node* node::find(node** start,node** end,int n){
    node *temp=*start;
    if(temp==NULL)return NULL;
    else{
        while(temp!=NULL){
            if(temp->data==n)return temp;
            else temp=temp->next;
        }
        return NULL;
    }
}

int main(){
node *start=NULL,*end=NULL;
int choice,flag=0;
while(1){
    cout<<"\n1.Exit\n2.Insert at end\n3.Insert at front\n4.Insert after\n5.Insert before\n6.Display\n7.Delete last\n8.Delete first\nMake Choice : ";
    cin>>choice;
    switch(choice){
        case 1: flag=1;
            break;
        case 2: start->insert_end(&start,&end);
            break;
        case 3: start->insert_beg(&start,&end);
            break;
        case 4: start->insert_after(&start,&end);
            break;
        case 6: start->display(&start,&end);
            break;
        case 7: start->delete_end(&start,&end);
            break;
        case 8: start->delete_start(&start,&end);
            break;
        default:cout<<"Wrong input\n";
    }
    if(flag==1)break;
}
}

当我调用insert_after()并给出元素之后我得到一个分段错误(核心转储),在该元素之后输入新元素与链接列表sample output when input same as a element in linked list! [sample output when input is different from any previous linked list element

中的任何元素相同

2 个答案:

答案 0 :(得分:1)

问题在于insert_after的成功案例:

node *obj = new node(n);
obj->prev = pos;
obj->next = pos->next;
pos->next->prev = obj; // <==
pos->next = obj;

如果我们有一个node的列表,这是我们要查找的node该怎么办,所以pos指向它。在这种情况下,pos->nextNULL,因此pos->next->prev的分配涉及解除引用NULL,这可能是您的段错误的原因。

那部分应该是:

if (pos->next) {
    pos->next->prev = obj;
}
else {
    // no next? must be at the end
    *end = obj;
}

也就是说,所有node方法都应该是自由函数,而不是类方法。您对insert_after的致电应该如下:

case 4:
    insert_after(&start,&end);
    break;

按原样,由于您以start作为NULL开头,所有来电都是未定义的行为 - 但您不需要它们作为方法,因为您&#39 ;只能通过startend指针访问数据。

最后,为什么会这样?

cin.clear();
cin.ignore(10000,'\n');

我很确定你在这个程序中不需要它。

答案 1 :(得分:0)

一个很大的问题是你在start上调用一个函数,即NULL,导致未定义的行为。

在调用任何内容之前实例化start

E.g。这很糟糕:

node *start=NULL,*end=NULL;
// ...
case 4: start->insert_after(&start,&end);

您可能需要重新考虑您的设计。

因此,我建议您使用std::vector来实现您的行为。