2013-04-30 91 views
1

我有機會爲一些C練習獲得一些額外的積分。其任務是增強程序使用頭部和尾部指針(用於FIFO隊列)以避免在提取函數循環時不必要的。指針隊列提取在C中無限循環

Insert()工作正常。它設置尾部和頭部,但extract()總是運行到無限循環或崩潰。 MinGW gcc顯示沒有任何額外的警告(-Wall),所以我在這裏有點困惑。

我做了一些調試,發現了線路,事情發生在未知宇宙中的某個地方......

queue->previous->next = queue->previous; // works 
    *head = (*head)->next; // loses pointer 
    free(queue); // as it should be, 
    return qtail; // caller function loses queue 

有趣的是,原代碼(在此之前)工作正常,不會丟失指向隊列的指針。我重寫了整個程序(清理了我的爛攤子),但仍然有問題。

程序輸出:

queue tester 

insert 0: first head: first, tail: first 
insert 1: second head: second, tail: first 
insert 2: third head: third, tail: first 
insert 3: foruth head: foruth, tail: first 
insert 4: some head: some, tail: first 
insert 5: another head: another, tail: first 
insert 6: last head: last, tail: first 

*** 

extracting last head: last, tail: first 
extracting ê7H head: ê7H, tail: first 
extracting ê7H head: ê7H, tail: first 
extracting ê7H head: ê7H, tail: first 

…依此類推,直到程序是由按Ctrl +ç

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

#define MAXLEN 50 
#define MAX 7 

typedef struct qelement *qpointer; 

typedef struct qelement { 
    char name[ MAXLEN ]; 
    qpointer next, previous; 

} qelement; 

qpointer insert(char *name, qpointer queue, qpointer *head, qpointer *tail); 
qpointer extract(qpointer queue, qpointer *head, qpointer *tail); 

qpointer insert(char *name, qpointer queue, qpointer *head, qpointer *tail) { 

    qpointer new = (qpointer)malloc(sizeof(qelement)); 
    strcpy(new->name, name); 

    if(queue != (qpointer)NULL) { 
     new->next = queue; 
     queue->previous = new; 
     (*head) = new; 
    } 
    else { 
     new->next = new; 
     (*head) = new; 
     (*tail) = new; 
    } 
    new->previous = new; 
    return new; 
    } 

qpointer extract(qpointer queue, qpointer *head, qpointer *tail) { 

    qpointer qtail =(*head); 

    if(queue == (qpointer)NULL) 
     return (qpointer)NULL; 
    else { 
     if(queue->previous != queue) { 
      free(queue); 
      (*head)=NULL; 
      (*tail)=NULL; 
      return (qpointer)NULL; 
     } 
     else { 
      queue->previous->next = queue->previous; 
      *head = (*head)->next; 
      free(queue); 
      return qtail; // usually main program loses queue after this. 
     } 
    } 
} 




int main (void) { 

    int i; 

    qpointer qptr =NULL; 
    qpointer head =NULL ; 
    qpointer tail =NULL ; 

    char teksti[MAX][MAXLEN] = { 
     "first", "second", "third", "foruth", "some", "another", "last" 
    }; 

    /* insert into queue */ 
    printf("\n queue tester \n"); 
    for (i =0; i<= MAX-1 ; i++) { 

     printf("\n insert %d: %s", i , teksti[i]); 
     qptr= insert(teksti[i], qptr, &head, &tail); 
     printf(" head: %s, ", head->name ? head->name : "no data"); 
     printf(" tail: %s ", tail->name ? tail->name : "no data"); 
    } 
    printf("\n\n"); 

    /* remove from queue */ 
    printf("\n ***\n"); 
    while ( qptr != NULL) { 

     printf("\n extracting %s ",qptr->name); 
     printf(" head: %s, ", head->name ? head->name : "no data"); 
     printf(" tail: %s ", tail->name ? tail->name : "no data"); 
     qptr = extract(qptr, &head, &tail); 
    } 

    return(0); 
} 

感謝終止!

+0

你可能要考慮有雙鏈表進行修改。 – 2013-04-30 18:43:18

+0

不知道你是否知道這個,OP,但你可能會覺得這很有用:[sys/queue.h](http://www.manpagez.com/man/3/queue/) – 2013-04-30 19:48:46

+0

如果這不是雙鏈表(帶 - >上一個和 - >下一個),那麼這是什麼?是的,我已經看到了sys/queue.h,但是原始任務不使用隨時可用的函數和結構。 – mtjjarvin 2013-05-01 09:31:36

回答

1

應該如下

qpointer extract(qpointer queue, qpointer *head, qpointer *tail) { 

    qpointer qtail =(*head); 

    if(queue == (qpointer)NULL) 
     return (qpointer)NULL; 
    else { 
     if(queue->next == queue) { 
      free(queue); 
      (*head)=NULL; 
      (*tail)=NULL; 
      return (qpointer)NULL; 
     } 
     else { 
      queue->next->previous = queue->next; 
      *head = (*head)->next; 
      free(queue); 
      return *head; // qtail already free 
     } 
    } 
} 
+0

感謝您的回答。至少我現在可以繼續前進。 – mtjjarvin 2013-05-01 09:26:37

+0

這是很好的服務。 – BLUEPIXY 2013-05-01 10:10:18