Search code examples
cstructqueuesingly-linked-listfunction-definition

Cannot access memory error for character array in struct - C


I am attempting to create a queue using a linked list in C. I am using two structs to represent the queue and each node which are as follows.

#define DATA_MAX 100

struct QueueNode_ch 
{
    struct QueueNode_ch* next;
    char data[(DATA_MAX + 1)];
};
typedef struct QueueNode_ch QueueNode_ch;

struct Queue_ch
{
    struct QueueNode_ch* front;
    struct QueueNode_ch* rear;
    int count;
};
typedef struct Queue_ch Queue_ch;

I then use these the following functions to initialize the queue and the nodes.

int initQueue_ch(Queue_ch* q)
{
    q = (Queue_ch*)malloc(sizeof(Queue_ch));
    q->count = 0;
    q->front = NULL;
    q->rear = NULL;
    return 0;
}

int initQueueNode_ch(QueueNode_ch* node)
{
    node = (QueueNode_ch*)malloc(sizeof(QueueNode_ch));
    node->next = NULL;
    node->data[0] = '\0';
    return 0;
}

Upon running my enqueue function I get a seg fault due to a strcpy function and when debugging gdb says it cannot access the memory of the node I am attempting to add. The enqueue code is as follows:

int enqueue_ch(Queue_ch* q, char* data)
{
    if(strlen(data) > (DATA_MAX + 1))
        return 1;
    QueueNode_ch* tmp;
    initQueueNode_ch(tmp);
    strncpy(tmp->data, data, DATA_MAX);
    if(isEmpty_queue_ch(q))
        q->rear = q->front = tmp;
    else
    {
        q->rear->next = tmp;
        q->rear = tmp;
    }
    q->count++;
    return 0;
}

I will also include my main function as additional information.

#include <stdio.h>
#include "Queue.h"

int main()
{
    Queue_ch* queue;
    initQueue_ch(queue);
    enqueue_ch(queue, "hello");
    return 0;
}

As far as I can tell there should be plenty of space to copy the given string to the node. Would anyone have any idea what is failing and possible fixes?


Solution

  • int initQueue_ch(Queue_ch* q)
    {
        q = (Queue_ch*)malloc(sizeof(Queue_ch));
        q->count = 0;
        q->front = NULL;
        q->rear = NULL;
        return 0;
    }
    

    This function is unusable. It ignores the value of q passed into it and does not return a pointer to the queue it initialized. C is strictly pass by value.

    int main()
    {
        Queue_ch* queue;
        initQueue_ch(queue);
        enqueue_ch(queue, "hello");
        return 0;
    }
    

    This code never gives queue any value and passes a garbage value to initQueue_ch (which it ignores) and then a garbage value to enqueue_ch.