1

現在、作成中のリンク リストに問題があります。基本的に何が起こっているかというと、関数内でヘッドノードを解放すると、関数自体で機能します。しかし、メイン関数からリンクされたリストにアクセスしようとすると、最近解放された head にアクセスしますが、解放されたペイロードは 1 つだけです。

ここに私のコードのスニペットがあります:

struct item  
{
   UINT   time ;          
   UINT   id ;            
   UINT   event ;          
   struct item  *next ;    
};

これは、3 つの異なるペイロードを含むノードの構造体です。これが私の初期化です。練習用に 3 つのノードを手動で初期化したことに注意してください。

struct item *head=NULL, *tail=NULL, *trail=NULL, *end=NULL;    
head=malloc(sizeof(struct item));
trail=head;
trail->next=NULL;

//TEST
{
    head=malloc(sizeof(struct item));
    trail=head;
    trail->next=NULL;

    head->time=50;
    head->event=100;
    head->id=1989;

        //printf("head->time: %d\nhead->event: %d\nhead->id: %d\n",head->time,          head->event, head->id);
        //printf("trail->time: %d\ntrail->event: %d\ntrail->id: %d\n",trail->time,     trail->event, trail->id);

    //this line of code produces a single payload in the linked list
    tail=malloc(sizeof(struct item));
    trail->next=tail;
    tail->time=1;
    tail->event=2;
    tail->id=3;
    trail=tail;
    //up until here
    /*
    tail=malloc(sizeof(struct item));
    trail->next=tail;
    trail=tail;
    // three lines of code needed to create a linked list
    */

    //this is linked to the code above
    tail=malloc(sizeof(struct item));
    trail->next=tail;
    tail->time=5;
    tail->event=7;
    tail->id=60;
    trail=tail;

    trail->next=NULL;
    end=trail;//end of the linked list
        //printf("tail->time: %d\ntail->event: %d\ntail->id: %d\n\n\n",tail->time, tail->event, tail->id);

    //this code prints out the entire linked list
    trail=head;
    do
    {
        TEST printf("trail->time: %d\ntrail->event: %d\ntrail->id:     %d\n\n",trail->time, trail->event, trail->id);      
        trail=trail->next;    
    }
    while(trail!=NULL);
}
//creation of linked list complete
//test to traverse the linked list

数時間前にリンク リストを作成し始めたばかりのコメントは無視してください。ここに私の問題があります。関数内で free を使用してリンクされたリストの先頭を削除すると、実際に解放されますが、メイン関数でリンクされたリストをトラバースすると、3 つのノードが出力されます。これは、メイン関数でリンク リストをトラバースするために使用するコード行です。

trail=head;
int item=0;
do
{
    item++;
    printf("item %d = %d %d %d\n",item ,trail->time, trail->id, trail->event);
    trail=trail->next;
}
while(trail!=NULL);

そして、これが頭を削除するために使用する関数です。

void list_head_delete(struct item *head)
{
    struct item *trail;    
    trail=head;
    trail=trail->next;    
    free(head);
    head=trail;
}

リンクされたリストをトラバースすると、通常は次のように出力されます。

item 1 = 50 1989 100
item 2 = 1 3 2
item 3 = 5 60 7

関数を呼び出してヘッドを削除し、リンクされたリストを再度トラバースすると、次の出力が得られます。

item 1 = 0 1989 100
item 2 = 1 3 2
item 3 = 5 60 7
4

1 に答える 1

3

削除関数の署名は次のとおりです: void list_head_delete(struct item *head). この署名を使用して、headノードにポインターを渡すためstruct node、ポインターが参照する を変更できますが、ポインター自体を変更することはできません。C では、関数の引数は値渡しであるため、渡す実際のポインターは単なるコピーであり、それへの変更は、たとえば、関数内のポインターのコピーhead=trail;のみになります。関数が戻ると、解放されたメモリを参照する元のアドレスが含まれます。head

ヘッド ポインターが指すものを変更したい場合は、ポインターにポインターを渡す必要があります。

void list_head_delete(struct item **head);

head引数を使用する場合、この余分なレベルの参照に対処するには、delete 関数を変更する必要があります。

または、関数の戻り値として新しいリストを返すこともできます。

struct node *list_head_delete(struct item *head);

// ... and to use it:
head = list_head_delete(head);
于 2012-08-29T05:25:19.760 に答える