user3591210
user3591210

Reputation: 83

C Segmentation fault when I try to enqueue

I'm making a producer/ consumer model where the producers need to enqueue int values and the consumers dequeue them. Whenever I try to enqueue an int, I get a segmentation error.

Here is the relevant queue code:

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

typedef struct Node {
    int item;
    struct Node* next;
} Node;

typedef struct Queue {
    Node* head;
    Node* tail;

    void (*enqueue) (struct Queue* queue, int value);
    int (*dequeue) (struct Queue* queue);
    int (*queueEmpty) (struct Queue* queue);
    int size;
} Queue;

void enqueue (Queue* queue, int item){
    Node* n = (Node*) malloc (sizeof(Node));
    n->item = item;
    n->next = NULL;

    if (queue->head == NULL) { // no head
        queue->head = n;
    } else{
        queue->tail->next = n;
    }
    queue->tail = n;
    queue->size++;
}

Queue* newQueue(){
    Queue* queue;
    queue->size = 0;
    queue->head = NULL;
    queue->tail = NULL;
    queue->enqueue = &enqueue;
    queue->dequeue = &dequeue;
    queue->queueEmpty = &queueEmpty;
    return queue;
}

Then I have this as a shared resource in the prodcons.c file:

Queue* queue;

Initialization in main:

queue = newQueue();

Producer code:

void* producer(void* arg) {

    int x;

    for (x = 0; x <= n; x++){
        pthread_mutex_lock(&lock);
        while(queueSize(queue) == maxsize){
            pthread_cond_wait(&lock, &empty)
        }
        enqueue(queue, x);
        pthread_mutex_unlock(&lock);
    }
      return(NULL);
}

Upvotes: 1

Views: 1064

Answers (1)

Mahonri Moriancumer
Mahonri Moriancumer

Reputation: 6003

As pointed out by Johnny Mopp's comment above, the segmentation fault is caused here:

Queue* newQueue(){
    Queue* queue;
    queue->size = 0;   /**** Seg-fault ****/

The newly defined Queue pointer 'queue' has not been set to point at anything in particular. Hence, it is likely pointing at some bizarre memory location that doesn't actually exist.

Treated as though it is pointing at a legitimate location, the code tries to zero 'queue->size'. When the processor calculates "bizarre memory location" + "the offset of the size element within the struct queue", it ends up with an address that is not listed in the process' memory map. This causes an unrecoverable error known as a Segmentation Fault.


FIX:

Change:

Queue* newQueue(){
    Queue* queue;

To:

Queue* newQueue(){
Queue* queue = malloc(sizeof(*queue));
   /* Check here if malloc() was successful */

Upvotes: 1

Related Questions