0

以下のコードでポインターを正しく実装したと思います。しかし、それはセグメンテーション違反を引き起こします。誰かが理由を説明できますか?

struct list
{
    int index;
    struct list *next;
};
void add(struct list *l,int index)
{
    struct list *temp=l;
    if(l==NULL)
    {
        temp=(struct list *)malloc(sizeof(struct list));
        temp->index=index;
        temp->next=NULL;
        l=temp;
    }
    else
    {
        while(temp->next!=NULL)
        temp=temp->next;
        struct list *nnode=(struct list *)malloc(sizeof(struct list));
        nnode->index=index;
        nnode->next=NULL;
        temp->next=nnode;
    }
}

main()
{
        struct list *l;
        l=NULL;
        int el;
        scanf("%d",&el);
        add(l,el);
        while(l->next!=NULL)    //It causes seg fault
        {
            printf(" %d ",l->index);
            l=l->next;
        }
}
4

2 に答える 2

3

このコードは、あなたが思っていることをしません:

void add(struct list *l,int index)
{
    struct list *temp=l;
    if(l==NULL)
    {
        temp=(struct list *)malloc(sizeof(struct list));
        temp->index=index;
        temp->next=NULL;
        l=temp;
    }
...

パラメータlはポインタとして渡すだけなので、変更されません。lが指すものを変更するには、lのアドレスを渡す必要があります。

void add(struct list **l,int index)
{
    struct list *temp;
    if(*l==NULL)
    {
        temp=(struct list *)malloc(sizeof(struct list));
        temp->index=index;
        temp->next=NULL;
        *l=temp;
    }
...

そうしないと、変更が関数スコープの外に到達しません。

于 2012-11-18T07:57:53.963 に答える
2

このコードは、addを1回呼び出すだけでセグメンテーション違反になることはありませんが、他の関数を呼び出してリストを渡すと仮定します。それでもNULL、代わりにリストへのポインターへのポインターを送信する必要があります。

void add(struct list **l,int index)
{
    if(*l==NULL) {
        *l=(struct list *) malloc(sizeof(struct list));
    }
}

それ以外の場合NULLは、ポインタのコピーのみを初期化するため、またはこれが混乱する場合は、リストをmain()初期化して初期化を回避することができるため、addが戻るときにもそのままになります。add()

于 2012-11-18T07:50:12.613 に答える