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.