【问题标题】:Runtime error and wrong anwer Linked list运行时错误和错误答案 链表
【发布时间】:2015-06-07 07:33:25
【问题描述】:

我正在尝试解决this spoj problem。

这是我对 C 语言问题的解决方案:

#include<stdio.h>
#include<stdlib.h>
struct node{
    int data;
    struct node*next;
};
struct node* head=NULL;

void insertFront(int data)
{
    struct node*newnode=(struct node*)malloc(sizeof(struct node));
    newnode->data=data;
    newnode->next=NULL;
    newnode->next=head;
    head=newnode;
}
int returnSize(){
    int cnt=0;
    struct node*temp=head;
    while(temp!=NULL)
    {
        cnt++;
        temp=temp->next;
    }
    return cnt;
}
void insertAt(int position,int data)
{
    struct node*newnode=(struct node*)malloc(sizeof(struct node));
    newnode->data=data;
    newnode->next=NULL;
    if(head==NULL&&position>0)//marker1
    {
        head=newnode;
        return;
    }//marker2
    int cnt=returnSize();
    if(position>cnt)
    {
        struct node*var=head;
        while(var->next!=NULL)
        var=var->next;
        var->next=newnode;
        return;
    }
    int i;
    struct node*temp=head;
    if(position==0)
    {
    newnode->next=head;
    head=newnode;
    return;
    }
    else
    {
        for(i=0;i<position-1;i++)
        {
            temp=temp->next;
        }
        newnode->next=temp->next;
        temp->next=newnode;

    }   
}
void deleteAt(int position)
{
    if(head==NULL)
    {
        printf("empty");
        return;
    }
    int i,cnt=0;
    struct node*dummy=head;
        while(dummy->next!=NULL)
        {
            cnt++;
            dummy=dummy->next;
        }
        if(position>cnt)
        return;
    if(position==0)
    {
        struct node*temp=head;
        head=head->next;
        free(temp);
    }
    else
    {
        struct node*temp=head;
        for(i=0;i<position-1;i++)
        {
            if(temp!=NULL)
            temp=temp->next;
            else
            return;
        }
        temp->next=temp->next->next;
    }
}
void deleteFront()
{
    if(head==NULL)
    {
        printf("empty");
        return;
    }
    struct node*temp=head;
    head=head->next;
    free(temp);
    if(head==NULL)
    {
        printf("empty");
        return;
    }
}
void print()
{
    struct node*temp=head;
    while(temp!=NULL)
    {
        printf("%d ",temp->data);
        temp=temp->next;
    }
    printf("\n");
}
int main()
{ 
char a;
do{

    char tmp;
    int b,c;
    scanf("%c",&a);
    if(a=='r')
    {
        deleteFront();

        print();
    }
    else if(a=='i')
    {
        scanf("%d",&b);
        scanf("%d",&c);
        insertAt(b,c);  
        print();
    }
    else if(a=='f')
    {
        scanf("%d",&b);
        insertFront(b);

        print();
    }
    else if(a=='d')
    {
        scanf("%d",&b);
        deleteAt(b);

        print();
    }
    scanf("%c",&tmp);
}while(a!='q');
    return 0;
}

如果我在函数insertAt() 中以注释行的形式删除我标记为marker 的行,我会得到segfault。 当我使用它们时,我得到了错误的答案。我测试了很多案例,但我无法弄清楚我错在哪里。

有人可以帮我吗?

【问题讨论】:

  • 为什么要删除这些行?一种建议是在满足条件(head==NULL 和 position > 0)时调用 insertFront。
  • 无论如何我在条件范围内做了同样的事情对吗?
  • 我的问题是为什么要删除这些行?还要提出您收到错误结果的测试用例。
  • 最初 i 虽然条件将通过 position>cnt 条件进行检查。但那不是真的。而且我不知道程序失败的测试用例。
  • 错误。我错过了一个“\n”,这让我有很多不成功的提交。现在被接受了。非常感谢@envy_intelligence 抽出宝贵时间 :)

标签: c linked-list c99


【解决方案1】:

首先,我建议您看看这个问题:Do I cast the result of malloc?... 可以说,就维护而言,最好遵循的模式看起来更像这样:

foo *bar = malloc(sizeof *bar);
if (bar == NULL) {
    /* handle allocation error */
}

这样,如果您必须更改 bar 的类型,您就不太可能忘记在某处替换类型名;如果您使用此模式,您将不太可能在维护期间创建新错误。


newnode->next=NULL; /* <--- THIS IS UNNECESSARY */
newnode->next=head; /* <--- because this ends up being the value immediately after */

在您使用过malloc 并且忽略检查其返回值的任何地方都存在潜在的空指针取消引用。请参阅上面的模式。

insertAt 中存在潜在的空指针取消引用,此处:temp=temp-&gt;next; 和此处:newnode-&gt;next=temp-&gt;next;。当head 为NULL 时,标记之间的代码会保护您的程序免受此空指针引用的影响...但这并不是可能触发此空指针取消引用的唯一情况。

deleteAt 中存在潜在的空指针取消引用,此处:temp-&gt;next=temp-&gt;next-&gt;next;


您确实应该在每次使用时检查scanf 的返回值。


为了将来参考,请修正您的制表键,以便我们可以更轻松地为您提供帮助...如果到目前为止只有我回答了您的问题,我不会感到惊讶。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-03
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多