简体   繁体   中英

Pointer queue extracting goes infinite loop in C

I got a chance to gain some extra points for a couple of C exercises. The task is to enhance program to use head and tail pointers (for FIFO queue) to avoid unneccessary while loops at extract function.

Insert() works fine. It sets the tail and head, but extract() always runs to the infinite loop or crashes. MinGW gcc shows no any extra warning ( -Wall ), so I am a bit confused here.

I did some debugging and found the lines, where things goes to somewhere in the unknown universe…

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

Funny enough, that original code (before this) works fine without losing pointer to queue. I rewrote entire program (cleaned my mess), however still having the issue.

Program output:

 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

… and so on until program is terminated by 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);
}

Thanks!

should be modified as follows

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM