dfmaaa1
dfmaaa1

Reputation: 77

Why does my queue throw a memory segmentation error when I try to dequeue?

I coded a Queue, the enqueuing function works correctly. It adds the new node to the back of the list. To save time, I used another pointer for the dequeuing method. I used a tail pointer that points to the oldest node. During queue creation(first node), the head pointer is assigned to the tail pointer. After that, in the dequeuing function, the tail pointer becomes its parent, and then the pointer is freed, and then the structure is returned. Now, when I coded a program that tests the queue, when dequeue() is called, it throws a memory segmentation error. Why?

Here's the code of the queue:

#include <stdio.h>
#include <stdlib.h>
/*uncomment the 4th line of size is more important to you than speed. The program will then take
more cpu cycles to read certain members of the structure, but it wont use padding, which wastes memory 
but increases speed.*/
//#define SIZE_OVER_SPEED
#ifdef SIZE_OVER_SPEED
    #pragma pack(1)
#endif
struct node{
    int data;
    struct node *next;
    struct node *parent;
};
#ifdef SIZE_OVER_SPEED
    #pragma pack(0)
#endif
typedef struct node _LINKED_LIST_QUEUE;
void enqueue(int,_LINKED_LIST_QUEUE**,_LINKED_LIST_QUEUE*);
void enqueue(int value, _LINKED_LIST_QUEUE **queue_head, _LINKED_LIST_QUEUE *tail){
    if(*queue_head==NULL){
        *queue_head=(_LINKED_LIST_QUEUE*)malloc(sizeof(_LINKED_LIST_QUEUE));
        if(*queue_head==NULL){
            perror("[malloc]");
            exit(EXIT_FAILURE);
        }
        (**queue_head).data=value;
        (**queue_head).parent=NULL;
        (**queue_head).next=NULL;
        tail=*queue_head;
        return;
    }
    _LINKED_LIST_QUEUE *save_head=*queue_head;
    *queue_head=(_LINKED_LIST_QUEUE*)malloc(sizeof(_LINKED_LIST_QUEUE));
    if(*queue_head==NULL){
            perror("[malloc]");
            exit(EXIT_FAILURE);
    }
    (**queue_head).data=value;
    (**queue_head).parent=NULL;
    (**queue_head).next=save_head;
    (*save_head).parent=*queue_head;
}
_LINKED_LIST_QUEUE dequeue(_LINKED_LIST_QUEUE *tail, int *SIGEND){
    _LINKED_LIST_QUEUE retstruct=*tail;
    if((*tail).parent==NULL){
        *SIGEND=1;
    }
    tail=(*tail).parent;
    free((*tail).next);
    return retstruct;
}

Here's the code of the tester program.

#include "main.c"
void normal_traverse(_LINKED_LIST_QUEUE *head){
    _LINKED_LIST_QUEUE *selected=head;
    while(selected!=NULL){
        printf("%d\t",(*selected).data);
        selected=(*selected).next;
    }
    puts("");
}
int main(){
    _LINKED_LIST_QUEUE *head, *tail;
    int end=0;
    head=NULL;
    enqueue(1,&head,tail);
    enqueue(2,&head,tail);
    enqueue(3,&head,tail);
    enqueue(4,&head,tail);
    normal_traverse(head);
    printf("%d\n",(dequeue(tail,end)).data);
    printf("%d\n",(dequeue(tail,end)).data);
    printf("%d\n",(dequeue(tail,end)).data);
    printf("%d\n",(dequeue(tail,end)).data);
    return 0;
}

Upvotes: 0

Views: 66

Answers (1)

dfmaaa1
dfmaaa1

Reputation: 77

@Gerhardh pointed out that the head pointer was being assigned to the local copy of tail'. So, I made tail` a double pointer. That solved my problems.

Upvotes: 1

Related Questions