简体   繁体   中英

C queue implementation using void* - good or bad practice?

I have implemented a basic queue structure in C using void pointers. The procedure is as follows:

  • initializing the structure - I set the size of the variable type to be stored in the queue
  • push - I pass the pointer to the variable to be stored, the queue then grabs a copy for itself
  • front - the structure returns a void* to the element in front. I may just grab the pointer, or 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)

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM