I'm completely new to C and I'm trying to implement a queue data structure. I don't know much about using pointers and storing data, so I'm having difficulty starting. The queue works as a fixed size circular buffer.
I only need a single queue_t. The queue_t or struct queue contains a long * that holds the data stored in the queue. It is also important that there are no memory/data leaks in my code.
I was just wondering if I could receive some help on how exactly to start, especially with the queue_new function, but also the other functions like enqueue as well? I'm sure I will need to use functions such as malloc. Here is the code I'm starting out with:
/*
* Queue implementation.
*
*/
#include <assert.h>
#include <stdlib.h>
#include "queue.h"
/** The main data structure for the queue. */
struct queue{
unsigned int back; /* The next free position in the queue
* (i.e. the end or tail of the line) */
unsigned int front; /* Current 'head' of the queue
* (i.e. the front or head of the line) */
unsigned int size; /* How many total elements we currently have enqueued. */
unsigned int capacity; /* Maximum number of items the queue can hold */
long *data; /* The data our queue holds */
};
/**
* Construct a new empty queue.
*
* Returns a pointer to a newly created queue.
* Return NULL on error
*/
queue_t *queue_new(unsigned int capacity) {
/* needs finishing */
queue_t *q = NULL;
return q;
}
/**
* Check if the given queue is empty
*
* Returns a non-0 value if the queue is empty, 0 otherwise.
*/
int queue_empty(queue_t *q) {
assert(q != NULL);
/* needs finishing */
return 0;
}
/*
* Check if the given queue is full
*
* Returns a non-0 value if the queue is empty, 0 otherwise.
*/
int queue_full(queue_t *q) {
assert(q != NULL);
/* needs finishing */
return 0;
}
/**
* Enqueue a new item.
*
* Push a new item into our data structure.
*/
void queue_enqueue(queue_t *q, long item) {
assert(q != NULL);
assert(q->size < q->capacity);
/* needs finishing */
}
/**
* Queue size.
*
* Queries the current size of a queue (valid size must be >= 0).
*/
unsigned int queue_size(queue_t *q) {
assert(q != NULL);
/* needs finishing */
return 0;
}
/**
* Dequeue an item.
*
* Returns the item at the front of the queue and removes an item from the
* queue.
*
* Note: Removing from an empty queue is an undefined behavior (i.e., it could
* crash the program)
*/
long queue_dequeue(queue_t *q) {
assert(q != NULL);
assert(q->size > 0);
/* needs finishing */
return -1;
}
/**
* Delete queue.
*
* Remove the queue and all of its elements from memory.
*
* Note: This should be called before the proram terminates.
*/
void queue_delete(queue_t* q) {
assert(q != NULL);
/* needs finishing */
}
The code references a queue.h file which acts as an interface, which I will provide here:
#ifndef _QUEUE_H
#define _QUEUE_H
/** Our queue type (fields are hidden in the implementation file). */
typedef struct queue queue_t;
/**
* Construct a new empty queue.
*
* Returns a pointer to a newly created queue.
* Return NULL on error
*/
queue_t *queue_new(unsigned int capacity);
/**
* Check if the given queue is empty
*
* Returns a non-0 value if the queue is empty, 0 otherwise.
*/
int queue_empty(queue_t *q);
/**
* Check if the given queue is full.
*
* Returns a non-0 value if the queue is empty, 0 otherwise.
*/
int queue_full(queue_t *q);
/**
* Enqueue a new item.
*
* Push a new item into our data structure.
*/
void queue_enqueue(queue_t *q, long item);
/**
* Dequeue an item.
*
* Returns the item at the front of the queue and removes an item from the
* queue.
*
* Note: Removing from an empty queue is an undefined behavior (i.e., it could
* crash the program)
*/
long queue_dequeue(queue_t *q);
/**
* Queue size.
*
* Queries the current size of a queue (valid size must be >= 0).
*/
unsigned int queue_size(queue_t *q);
/**
* Delete queue.
*
* Remove the queue and all of its elements from memory.
*
* Note: This should be called before the program terminates.
*/
void queue_delete(queue_t *q);
#endif /* ifndef _QUEUE_H */