Reputation: 3553
I am using a self-written queue library with the following structure:
#ifndef MYQUEUE_
#define MYQUEUE_
#ifndef SET_QUEUE_SIZE
#define SET_QUEUE_SIZE 10
#endif
typedef struct queue Queue;
/*
** Creates and initializes the queue and prepares it for usage
** Return a pointer to the newly created queue
*/
Queue* QueueCreate();
/*
** Add an element of a generic type to the queue
*/
void Enqueue(Queue* queue, void* element);
/*
** Delete the queue from memory; set queue to NULL
** The queue can no longer be used unless QueueCreate is called again
*/
void QueueDestroy(Queue** queue);
/*
** Return the number of elements in the queue
*/
int QueueSize(Queue* queue);
/*
** Return a pointer to the top element in the queue
*/
void* QueueTop(Queue* queue);
/*
** Remove the top element from the queue
*/
void Dequeue(Queue* queue);
#endif //MYQUEUE_
Now, I'm having issues with putting it in and receiving it out from the circular queue. The queue itself has been tested and shouldn't give any issues.
Running the code below (it's an extract of the total program) my two prints don't print the same values. Where am I pointing wrong?
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "libs/myqueue.h"
struct package{
unsigned sensorId:12;
unsigned sequence:4;
unsigned flag:2;
unsigned sign:1;
unsigned value:12;
unsigned parity:1;
};
typedef struct package packs;
struct sensor_time{
packs myPack;
time_t time;
};
typedef struct sensor_time Sensor_Time;
Queue* queue = NULL;
int main(void){
queue = QueueCreate();
if(queue == NULL){
printf("Error creating circular buffer.\n");
exit(EXIT_FAILURE);
}
Sensor_Time * myData = malloc(sizeof(Sensor_Time));
myData->myPack.sensorId = 1;
myData->myPack.value = 20;
myData->time = time(NULL);
printf("Enqueued: id: %d, value: %d, time: %lu\n", myData->myPack.sensorId, myData->myPack.value, myData->time);
Enqueue(queue, (void *)myData);
Sensor_Time * mySens = (Sensor_Time *)QueueTop(queue);
printf("Data read: id: %d, value: %d time: %lu", mySens->myPack.sensorId, mySens->myPack.value, mySens->time);
return 1;
}
What gets printed:
For completeness, here the queue implementation:
/*----- Include Files -----*/
#include <stdlib.h>
#include <stdio.h>
#include "myqueue.h"
/*----- Variables -----*/
typedef void * DATATYPE;
struct queue{
DATATYPE elements[SET_QUEUE_SIZE];
size_t count;
int front;
int rear;
};
typedef struct queue Queue;
typedef Queue *myQueue;
/*----- QueueCreate -----*/
Queue* QueueCreate(void){
#ifdef DEBUG
printf("QueueCreate called.\n");
#endif
Queue* qu = malloc(sizeof(Queue));
qu->count = 0;
qu->front = 0;
qu->rear = 0;
return qu;
}
/*----- QueueCreate -----*/
void Enqueue(Queue* queue, DATATYPE element){
#ifdef DEBUG
printf("Enqueue called, on queue %p.", queue);
int location = queue->rear;
#endif
if(queue->count == SET_QUEUE_SIZE){
printf("Queue is full.\n");
}else{
queue->elements[queue->rear] = element;
queue->count++;
queue->rear++;
if(queue->rear == SET_QUEUE_SIZE - 1){
queue->rear = 0;
}
}
#ifdef DEBUG
printf(" Element added on location %d.\n", location);
#endif
}
/*----- QueueDestroy -----*/
void QueueDestroy(Queue** queue){
#ifdef DEBUG
printf("QueueDestroy called on %p\n", queue);
#endif
free(*queue);
*queue = NULL;
}
/*----- QueueSize -----*/
int QueueSize(Queue* queue){
#ifdef DEBUG
if(queue->count > 0){
printf("QueueSize called. Size is %d.\n", (int)queue->count);
}
#endif
return queue->count;
}
/*----- QueueTop -----*/
void* QueueTop(Queue* queue){
#ifdef DEBUG
printf("QueueTop called\n");
#endif
if(queue->count == 0){
return NULL;
}else{
return &(queue->elements[queue->front]);
}
return NULL;
}
/*----- Dequeue -----*/
void Dequeue(Queue* queue){
#ifdef DEBUG
printf("Dequeue called on %p.", queue);
int location = queue->front;
#endif
if(queue->count == 0){
printf("Queue is empty.\n");
}else{
queue->front++;
if(queue->front == SET_QUEUE_SIZE - 1){
queue->front = 0;
}
queue->count--;
}
#ifdef DEBUG
printf(" Removed element was on location %d.\n", location);
#endif
}
Upvotes: 0
Views: 613
Reputation: 110108
Your queue stores elements of type void*
. However, QueueTop
returns a pointer to the first element, which would make it of type void**
. The fact that the function is declared as returning void*
instead of DATATYPE*
makes this confusing, but it's legal because any pointer can be converted to void*
, including a double pointer.
When you add an element to the queue, you cast it from Sensor_Time *
to void*
. Later when calling QueueTop
, you take the return value and cast it to Sensor_Time *
, which is wrong, because it is actually a pointer to a pointer.
To fix, you'd need to either change QueueTop
to return an element rather than a pointer to an element, or change your calling code to dereference the returned pointer.
Upvotes: 2