Reputation: 3457
I have implemented a basic queue structure in C using void pointers. The procedure is as follows:
memcpy()
it to have a local copy.The struct itself looks like this:
struct queue
{
void* start; //pointer to the beginning of queue
void* end; //-||- to the end
size_t memsize; //size of allocated memory, in bytes
size_t varsize; //size of a single variable, in bytes
void* initial_pointer; //position of the start pointer before pop() operations
};
start and end are just void pointers that point to some location within the currently allocated memory block. If I push elements on the queue, I increment the end pointer by varsize
. If I pop(), I just decrement the end pointer also by varsize
.
I don't think I should post the functions code here, it's over 100 lines.
The question: is this considered a good or a bad practice? Why (not)?
Note: I'm aware that there are many other options for a queue in C. I'm just asking about the quality of this one.
EDIT: The implementation is available here: http:// 89.70.149.19 /stuff/queue.txt (remove the spaces)
Upvotes: 6
Views: 3381
Reputation: 78903
You really don't show us enough to be sure about your implementation. void*
for the user data items is fine, you can't do much otherwise in C.
But I strongly suspect that you have an internal list element type that you use to manage the individual items, something like
struct list_item {
struct list_item* next;
void* data;
};
If that is the case and your start
and end
pointers are pointing to such elements, you definitively should use your element type in the struct queue
declaration:
struct queue
{
struct list_item* start; //pointer to the beginning of queue
struct list_item* end; //-||- to the end
size_t memsize; //size of allocated memory, in bytes
size_t varsize; //size of a single variable, in bytes
struct list_item* initial_pointer; //position of the start pointer before pop() operations
};
For this to work you don't even have to expose the definition of struct list_item
to the user of struct queue
.
Upvotes: 2
Reputation:
It's OK to use void *
if you don't know the type and size of the objects to be stored in the queue (in fact, the C standard library follows the same approach, see the memcpy()
and qsort()
functions for some examples). However, it would be better to use size_t
(or ssize_t
if you need a signed data type) for specifying the size of the elements stored in the queue.
Upvotes: 8