0
votes

i got a queue file from some old repo without any documentation, i was trying to enqueue and de queue data from it

the .h file is like below

#include"limits.h"
#include"stdio.h"
#include"pthread.h"
#include"unistd.h"
#include"stdlib.h"
#include"string.h"
#include"time.h"
pthread_mutex_t lock;


typedef struct{
    int* message;
    void*in_array;
}data_pack;

 data_pack* createpack()
{

     data_pack* pack = malloc(sizeof( data_pack));
     return pack;
}

// Queue Structure
struct Queue {
    int front, rear, size; // front, rare and the size of the Queue
    unsigned long long capacity; // stores the capacity of the Queue
    data_pack** array; //2D array to store the array of arrays
    int* array_sizes; //1D array to store the number of elements of each array
    data_pack** remArray; //2D array to store the remaining array of arrays(used for flush)
};


// Creates a Queue
struct Queue* createQueue()
{
    struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));
    queue->front = queue->size = 0;
    queue->capacity = queue->size + 1;
    queue->rear = queue->capacity - 1;
    queue->array = (data_pack **)malloc(queue->capacity * sizeof(data_pack));// changed to my struct
    queue->array_sizes = (int *)malloc(queue->capacity * sizeof(int));



    if (pthread_mutex_init(&lock, NULL) != 0) {
            printf("\n mutex init has failed\n");
            return 0;
        }
    return queue;
}

// Queue is empty when size is 0
int isEmpty(struct Queue* queue)
{

    return (queue->size == 0);

}

// Function to add an array to the queue.
// It changes rear and size
void enqueue(struct Queue* queue, data_pack arr[], int n)
{
    int i=0;
    pthread_mutex_lock(&lock);// lock variables
    queue->rear = (queue->rear + 1) % queue->capacity;
    queue->array[queue->rear] = (data_pack *)malloc(n*sizeof(data_pack));
    if(queue->array[queue->rear]==NULL) printf("Error in memory\n");
    for(i=0;i<n;i++){
        queue->array[queue->rear][i] = arr[i];// u need to input struct here

    }
    queue->array_sizes[queue->rear] = n;
    queue->size = queue->size + 1;
    queue->capacity = queue->capacity + 1;
    queue->array = (data_pack**)realloc(queue->array,queue->capacity*sizeof(data_pack));
    if(queue->array == NULL) printf("Not 2d array");
    queue->array_sizes = (int*)realloc(queue->array_sizes,queue->capacity*sizeof(int));
    if(queue->array_sizes == NULL) printf("not 1dn array sizes");
    pthread_mutex_unlock(&lock);// unlock variables

}

// Function to remove an array from queue.
// It changes front and size
data_pack* dequeue(struct Queue* queue)
{
    int i=0;
    pthread_mutex_lock(&lock);// lock variables
    int len = queue->array_sizes[queue->front];
    data_pack* deqArray = (data_pack*)malloc(len*sizeof(data_pack));
    if (isEmpty(queue))
        return 0;

    for( i=0;i<queue->array_sizes[queue->front];i++){

        deqArray[i] = queue->array[queue->front][i];
    }


    queue->front = (queue->front + 1) % queue->capacity;
    queue->size = queue->size - 1;
    pthread_mutex_unlock(&lock);// unlock variables
    free(queue->array[queue->front-1]);

    return deqArray;
}

// Function to flush all the arrays and its elements from the queue.
data_pack** flush(struct Queue* queue)
{
    int i=0;
    int j=0;
    queue->remArray = (data_pack **)malloc(queue->size * sizeof(data_pack));
    int k=0;
    for( i=queue->front;i<=queue->rear;i++){
        int len = queue->array_sizes[i];
        queue->remArray[k] = (data_pack *)malloc(len*sizeof(data_pack));
        for( j=0;j<len;j++){

            //queue->remArray[k][j] = queue->array[i][j];
        }
        free(queue->array[i]);

        k++;
    }
    free(queue->array);
    free(queue->array_sizes);
    queue->front = queue->size = 0;
    queue->capacity = queue->size + 1;
    queue->rear = queue->capacity - 1;
    queue->array_sizes = (int *)malloc(1 * sizeof(int));
    queue->array = (data_pack **)malloc(1 * sizeof(data_pack));
    return queue->remArray;
}

// Function to know number of arrays in queue
int no_elements(struct Queue* queue)
{

    return queue->size;


}

In my code, I'm trying to enqueue element, get size of queue and dequeue element

struct Queue * send_data_queue;
data_pack data_to_send[0];
data_pack * rec_data;
typedef struct SenderData {
  unsigned short CommandCode;
  int DataSize;
  void * Data;
}
SenderData;

int cont[200];

SenderData data, dat;

int main(int argc, char * argv[]) {

  send_data_queue = createQueue();

  while (1) {
    data.DataSize = sizeof(cont);
    data.Data = & cont;
    data.CommandCode = 20;

    data_to_send[0].message = 20;
    data_to_send[0].in_array = & data;

    enqueue(send_data_queue, data_to_send, 1);

    int nos = no_elements(send_data_queue);
    printf("No of elements in q = %d\n", nos); // this is printing correctly

    rec_data = dequeue(send_data_queue);

    dat = ((SenderData * )(rec_data -> in_array)[0]); // i get error here Invalid use of void Expression

  }

  return 0;
}

Explaining my code

-I'm trying to enqueue an array which is int array of 200 Elements

I'm updating my struct data with required info such as size, command and the actual data

This queue utilizes a struct to pass data, so i update my struct data to this struct

Then i call enqueue function

then i check the queue size, its updating correctly

I'm trying to dequeue data

here I'm casting the data to struct which is Sender data

but at this point I'm getting error as Invalid Use of Void Expression

why is this giving such an error?

1

1 Answers

0
votes

On this line:

dat = ((SenderData * )(rec_data -> in_array)[0]);

The array subscript operator has higher precedence than the typecast operator. So the first thing that gets evaluated is rec_data -> in_array[0]. This dereferences a void * which is not allowed.

You either need to use parenthesis to apply the cast first:

dat = ((SenderData *)(rec_data->in_array))[0];

Or instead use the dereference operator instead of array indexing:

dat = *(SenderData *)rec_data->in_array;