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 styleMy ability to properly deallocate memory so that there is no memory leaksProperly handling memory allocation failureAnything else that you would like to addQueue.h#ifndef QUEUE_H_INCLUDED#define QUEUE_H_INCLUDEDtypedef 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.hvoid 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.hint 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
Implementing a generic Queue in C
c;generics;queue