循環リスト再実装

循環リスト - (void*)Pないと

もう少しシンプルに実装し直してみます。

前の時はlast変数を用意してリストへの追加が最後尾になるように実装したのですが、あまり必要なさそうなので今回は無しでやります。

#include <stdio.h>
#include <stdlib.h>

struct LIST {
    int data;
    struct LIST *next;
    struct LIST *prev;
};
typedef struct LIST LIST;

LIST *create_list(int data) {
    LIST *p;
    p = (LIST *)malloc(sizeof(LIST));
    if ( p == NULL ) {
        return NULL;
    }
    p->next = p;
    p->prev = p;
    p->data = data;
    
    printf("create %p\n",p);
    return p;
}

LIST *add_list (LIST *p,int data) {
    LIST *a = create_list(data);
    
    a->next = p->next;
    a->prev = p;
    p->next->prev = a;
    p->next = a;
    return a;
}

void free_list (LIST *p) {
    LIST *s = p;
    LIST *q;
    do {
        q = p;
        p = p->next;
        printf("free   %p\n",q);
        free(q);
        q = NULL;
    } while ( s!=p );
}

void delete_list (LIST *p) {
    LIST *s = p;
    p->prev->next = p->next;
    p->next->prev = p->prev;
    printf("free   %p\n",s);
    free(s);
    s = NULL;
}

void show_next_list (LIST *p) {
    LIST *s = p;
    do{
        printf("%d\n",p->data);
        p = p->next;
    }while( s!=p );
}

void show_prev_list (LIST *p) {
    LIST *s = p;
    do{
        printf("%d\n",p->data);
        p = p->prev;
    }while( s!=p );
}

int main (void) {
    LIST *head;
    LIST *p;
    
    head = create_list(100);
    p = add_list(head,200);
    p = add_list(p,300);
    p = add_list(p,400);
    p = add_list(p,500);
    
    delete_list(p); // 最後に追加したデータを削除
    
    puts("next:");
    show_next_list(head);
    
    puts("prev:");
    show_prev_list(head);
    
    free_list(head);
    
    return 0;
}

かなりシンプルになりました。

delete_listは削除したい値を検索するのではなく、削除したいリストのポインタを渡す仕様に変更しました。

そういえば話が変わりますが、freeって必要ないんですね。

Q 【free】
 獲得したメモリはプログラム終了時に、 free しなければならないのか。あるいは、するべきか。


 おそらく、殆どの処理系では、建前として、プログラムが終了した時点で獲得されたメモリは全て自動的に開放されることになっていると思われます。しかし、なぜだかプログラムを実行する度に空きメモリが減ってゆくという奇妙な現象が発生するシステムを目撃することもしばしばあるようです。

 獲得したメモリを全て free してから終了すれば、このような奇妙な現象を回避できる確率は高くなりますが、完璧であるとは限りません。

 いずれにしても、獲得したメモリを free しなくても構わない、という考え方の方が一般的であるようです。

(参考: comp.lang.c FAQ 7.24)

$B=i5i(JC$B8@8l(JQ&A(4)

freeのための処理を頑張って書いていたのですが・・・。

必要なのか必要じゃないのかよくわからないですね。