2012-04-08 7 views
2

Ich habe eine Datei mit einer doppelt verknüpften Liste, die eine Reihe von Prozess-IDs und einige Statusinformationen enthält.C Programmierung Linked-Liste und entfernen

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; 
}; 

Ich habe eine Methode, ein Element von meiner Liste zu entfernen:

{ 
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; 
     } 
    } 
    } 

Was mit meiner entfernen Funktion falsch ist? Ich bekomme scheinbar eine Endlosschleife, wenn ich versuche, meine Liste zu drucken. Zuvor dachte ich, es war die Art, wie ich kostenlos() aber anscheinend nicht aus den Antworten :)

Danke!

+0

Sie es normalerweise überwinden, indem malloc alles, was Sie in der Liste einfügen zuzuordnen. –

+1

Wie ** war ** es dann zugewiesen? –

Antwort

1

Wenn Sie einen Knotensatz next zu NULL hinzufügen.

Dann, wenn Sie alle frei, bis nächsten frei == NULL.

Wenn Sie einen Knoten entfernen. Aktualisiere Links und freien Knoten.

Auch; frei auf NULL ist ein Noop.

Valgrind ist ein unschätzbares Werkzeug bei der Arbeit an solchen Dingen.


Glauben Sie, Sie müssen noch ein paar Überprüfungen durchführen; D.h .:

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; 
     } 
    } 
} 

Vorausgesetzt, dass Sie die Liste etwas wie d.h .: bauen

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; 
} 
0

Ich weiß, Sie können nicht frei() etwas, das nicht von malloc zugeordnet wurde, Wie überwinde ich das?

Was ist zu überwinden? Entweder wurde etwas dynamisch zugewiesen und Sie müssen free() es, oder es wurde mit automatischer Speicherdauer zugewiesen und Sie nicht. Hier gibt es kein Problem.

In der Regel mit einem Licht wie diesem werden Sie malloc alles, damit Sie Dinge zuverlässig befreien können. Ansonsten wissen Sie nicht, wie sie zugewiesen wurden und können auf undefiniertes Verhalten stoßen.