2

プロセス識別子のセットといくつかの状態情報を含む二重リンクリストを含むファイルがあります。

struct pr7_process 
{ 
  pid_t pid;        /* process ID, supplied from fork() */ 
                /* if 0, this entry is currently not in use */ 
  int   state;      /* process state, your own definition */ 
  int   exit_status;    /* supplied from wait() if process has finished */
  struct pr7_process *next;   // a pointer to the next process
  struct pr7_process *prev;
};

/* the process list */

struct process_list
{
   struct pr7_process *head;
   struct pr7_process *tail;
};

リストの要素を削除する方法があります。

{
struct pr7_process *cur;
  for(cur = list->head; cur != NULL; cur = cur->next)
    {
      if (cur->pid == pid)
        {
          printf("cur pid: %d\n", cur->pid);
          cur->state = STATE_NONE;
          if(list->head == list->tail)
         {
           free(cur);
         }
         else
          {
            cur->prev->next = cur->next;
            cur->next->prev = cur->prev;
            free(cur);
          }
          break;
        }
     } 
  } 

削除機能の何が問題になっていますか?リストを印刷しようとすると、無限ループが発生するようです。以前は、free()を使用した方法だと思っていましたが、返信からではないようです:)

ありがとう!

4

2 に答える 2

1

nextに設定されたノードを追加する場合NULL

次に、すべてを解放したら、next==NULLまで解放します。

ノードを削除するとき。リンクと空きノードを更新します。

また; NULLでの無料はnoopです。

Valgrindは、そのようなことに取り組む際の非常に貴重なツールです。


もう少しチェックする必要があると信じてください。すなわち:

struct pr7_process {
    int pid;
    ...
} const new_proc = {
    0, 44, 0, NULL, NULL
};

void del(struct process_list *list, int pid)
{
    struct pr7_process *cur;

    for (cur = list->head; cur != NULL; cur = cur->next) {
        if (cur->pid == pid) {

            printf("cur pid: %d\n", cur->pid);

            if(list->head == list->tail) {
                free(cur);
                list->head = NULL;
                list->tail = NULL;
            } else if (cur == list->head) {
                list->head = list->head->next;
                free(cur);
                list->head->prev = NULL;
            } else if (cur == list->tail) {
                list->tail = cur->prev;
                free(cur);
                list->tail->next = NULL;
            } else {
                cur->prev->next = cur->next;
                cur->next->prev = cur->prev;
                free(cur);
            }
            break;
        }
    }
}

次のようなリストを作成するとします。

int push(struct process_list *list, int pid, int state)
{
    if (list->head == NULL) { /* or move this to where ever you see fit */
        if ((list->head  = malloc(sizeof(struct pr7_process))) == NULL)
            return -1;
        list->tail  = list->head;
        *list->tail = new_proc;
    } else {
        if ((list->tail->next  = malloc(sizeof(struct pr7_process))) == NULL)
            return -1;
        *list->tail->next = new_proc;
        list->tail->next->prev = list->tail;
        list->tail = list->tail->next;
    }
    list->tail->pid = pid;
    list->tail->state = state;

    return 0;
}

void wipe(struct process_list *list)
{
    struct pr7_process *node = list->tail;

    while (node != list->head) {
        node = list->tail->prev;
        free(list->tail);
        list->tail = node;
    }
    free(list->head);
    list->head = NULL;
    list->tail = NULL;
}

void prnt(struct process_list list, int dir)
{
    if (dir == 1) {
        while (list.head != NULL) {
            printf("%4d: %d\n", list.head->pid, list.head->state);
            list.head = list.head->next;
        }
    } else {
        while (list.tail != NULL) {
            printf("%4d: %d\n", list.tail->pid, list.tail->state);
            list.tail = list.tail->prev;
        }
    }
}

int main(void)
{
    struct process_list list = {NULL, NULL};

    push(&list, 331, 2); /* if(push() != -1) ... */
    push(&list, 332, 66);
    push(&list, 333, 47);

    prnt(list, 1);

    del(&list, 332);
    prnt(list, 1);

    wipe(&list);
    prnt(list, 1);

    return 0;
}
于 2012-04-08T03:33:06.053 に答える
0

mallocによって割り当てられていないものをfree()できないことは知っていますが、どうすればこれを克服できますか?

克服すべきことは何ですか?何かが動的に割り当てられて必要にfree()なるか、自動保存期間で割り当てられたのに必要ありません。ここでは問題ありません。

通常、このような照明を使用すると、mallocすべてを確実に解放できるようになります。そうしないと、それらがどのように割り当てられたかがわからず、未定義の動作に遭遇する可能性があります。

于 2012-04-08T03:28:01.053 に答える