指针队列提取在C中进行无限循环

时间:2013-04-30 18:40:43

标签: c queue infinite-loop

我有机会获得一些C练习的额外积分。任务是增强程序使用头尾指针(用于FIFO队列),以避免在提取函数时不必要的while循环。

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 + C

终止
#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);
}

谢谢!

1 个答案:

答案 0 :(得分: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
        }
    }
}