Skip to main content

Timeline for Implementing a generic Queue in C

Current License: CC BY-SA 3.0

15 events
when toggle format what by license comment
Sep 13, 2016 at 20:04 comment added chux @Luis Averhoff Re: "I also dont think I need to do memcpy in enqueue either." Consider { long double x = 1/7.0; enqueue(q, &x); } .... { long double y; dequeue(q, ....); How to call dequeue() to put a value in y? without a memcpy() in enqueue()? The address for x is long since invalid.
Sep 13, 2016 at 19:43 comment added chux Pass an long double* and only storing the pointer as you suggest obliges the calling code to allocate space and goes against OP's goal of "work any data type you give it". Pedantically your idea does not handle pointer to functions, which may not fit in void* - unless calling code allocates for that too. OP's interacts with calling code by passing a reference to the data, not the data itself (which may be of any size). OTOH I have, worked with libraries had the best/worst of both, when memSize <= sizeof(void*), no need to allocate, just store the value in a unionized void*.
Sep 13, 2016 at 19:04 comment added Luis Averhoff @chux Looking at the queuePeek a little bit more closely, it does not make sense to do a memcpy there because we can make queuePeek return a void * like return q->head->data else NULL instead. So at least in queuePeek, we dont have to do a memcpy. I also dont think I need to do memcpy in enqueue either. I should be able to newNode->data = data;. The only place I think I need to memcpy is in dequeue.
Sep 13, 2016 at 19:00 comment added coderodde @chux In that case you pass an long double* creating which is an alternative to storing explicitly in a queue node.
Sep 13, 2016 at 18:58 comment added chux Disagree with "Don't copy data". That idea makes sense if the data to be queued is always a pointer. Yet OP's goal is "work any data type you give it". Example. If my data was type long double, trying to copy that or its address into a void * would fail.
Sep 13, 2016 at 18:15 comment added Luis Averhoff I added a section called Improvement Example in the main post. Check it out when you can. Never mind. I'll make a follow up to this later.
Sep 13, 2016 at 16:09 comment added coderodde I suggest you do a follow-up question here in CR and rewrite your queue nodes to store only the (void*) pointers to the actual data objects. That way, it would be easier to discuss those issues.
Sep 13, 2016 at 15:52 comment added coderodde @LuisAverhoff Stand by, I will reply soon.
Sep 13, 2016 at 15:42 comment added Luis Averhoff Actually I think I'm over complicating things. If you look in testqueue.c, I call queuePeek and I pass in the address of the q and the address of an int variable that is to be modified. Why can't I simply do data = q->head->data? in the queuePeek function. The main objective of queuePeek is to pass reference to the data at the head of the queue.
Sep 13, 2016 at 15:37 comment added coderodde Don't do this. There is absolutely no guarantee that the nodes will be allocated in the heap continuously like array components. If you need to be capable to store NULL as well, one way to arrange it is to pass a void** to the peek operation. (A pointer to a pointer \$P\$ to an object.) Then, just write the data in the head of the queue to \$P\$. (Don't know how to explain that formally.)
Sep 13, 2016 at 15:31 comment added Luis Averhoff Cool I'm simply talking about setting the data appropriately(The rest I agree with you of course). Like instead of using memcpy in the peek function, maybe this would work? data = (char *)q->head->data + (q->sizeOfQueue * q->memSize) This would simply offset the ptr(in my mind) the correct amount.
Sep 13, 2016 at 15:26 comment added coderodde @LuisAverhoff I would rather stick to your pattern of returning a boolean as an indicator of the success of the called operation. If you, say, peek from an empty queue, don't modify anything pointed by *data, but return false. If not empty, return true and set data appropriately.
Sep 13, 2016 at 15:23 comment added Luis Averhoff So for queuePeek, I can have it return a void * like this return q->head->data; . For enqueue, I can do newNode->data = data; correct? It seems for dequeue that I'm going to have use memcpy.
Sep 13, 2016 at 15:15 history edited coderodde CC BY-SA 3.0
added 115 characters in body
Sep 13, 2016 at 15:10 history answered coderodde CC BY-SA 3.0