I wrote a generic Queue that could with work any data type you give it. The Queue
can do any the basic operations that you would expect a Queue
can do such as enqueue
, dequeue
, peek
and so on.
I would like you to critique me on:
- My general style
- My ability to properly deallocate memory so that there is no memory leaks
- Properly handling memory allocation failure
- Anything else that you would like to add
Queue.h
#ifndef QUEUE_H_INCLUDED
#define QUEUE_H_INCLUDED
typedef struct Node
{
void *data;
struct Node *next;
}node;
typedef struct QueueList
{
int sizeOfQueue;
size_t memSize;
node *head;
node *tail;
}Queue;
void queueInit(Queue *q, size_t memSize);
int enqueue(Queue *, const void *);
void dequeue(Queue *, void *);
void queuePeek(Queue *, void *);
void clearQueue(Queue *);
int getQueueSize(Queue *);
#endif /* QUEUE_H_INCLUDED */
Queue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Queue.h"
void queueInit(Queue *q, size_t memSize)
{
q->sizeOfQueue = 0;
q->memSize = memSize;
q->head = q->tail = NULL;
}
int enqueue(Queue *q, const void *data)
{
node *newNode = (node *)malloc(sizeof(node));
if(newNode == NULL)
{
return -1;
}
newNode->data = malloc(q->memSize);
if(newNode->data == NULL)
{
free(newNode);
return -1;
}
newNode->next = NULL;
memcpy(newNode->data, data, q->memSize);
if(q->sizeOfQueue == 0)
{
q->head = q->tail = newNode;
}
else
{
q->tail->next = newNode;
q->tail = newNode;
}
q->sizeOfQueue++;
return 0;
}
void dequeue(Queue *q, void *data)
{
if(q->sizeOfQueue > 0)
{
node *temp = q->head;
memcpy(data, temp->data, q->memSize);
if(q->sizeOfQueue > 1)
{
q->head = q->head->next;
}
else
{
q->head = NULL;
q->tail = NULL;
}
q->sizeOfQueue--;
free(temp->data);
free(temp);
}
}
void queuePeek(Queue *q, void *data)
{
if(q->sizeOfQueue > 0)
{
node *temp = q->head;
memcpy(data, temp->data, q->memSize);
}
}
void clearQueue(Queue *q)
{
node *temp;
while(q->sizeOfQueue > 0)
{
temp = q->head;
q->head = temp->next;
free(temp->data);
free(temp);
q->sizeOfQueue--;
}
q->head = q->tail = NULL;
}
int getQueueSize(Queue *q)
{
return q->sizeOfQueue;
}
TestQueue.c
#include <stdio.h>
#include <stdlib.h>
#include "Queue.h"
int main()
{
int val;
Queue q;
queueInit(&q, sizeof(int));
for(val = 0; val < 10; val++)
{
enqueue(&q, &val);
printf("The value %d has been enqueued.\n", val + 1);
}
printf("\n");
queuePeek(&q, &val);
printf("The value that is at the front of the queue is %d\n\n", val + 1);
while(getQueueSize(&q) > 0)
{
dequeue(&q, &val);
printf("%d has been dequeued.\n", val + 1);
}
return 0;
}
Output
int val while(q->sizeOfQueue > 0){dequeue(q, &val)} q->head = q->tail = NULL;
This of course would be in the clearQueue function. \$\endgroup\$