C指针和队列问题

时间:2014-06-23 11:17:14

标签: c pointers queue

我正在使用具有以下结构的自编队列库:

#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_

现在,我遇到了将其放入并从循环队列中接收出来的问题。队列本身已经过测试,不应该给出任何问题。

运行下面的代码(它是整个程序的摘录)我的两个打印件不会打印相同的值。我在哪里指错了?

#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;
}

打印的内容:

enter image description here

为了完整性,这里是队列实现:

/*----- 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
}

1 个答案:

答案 0 :(得分:2)

您的队列存储void*类型的元素。但是,QueueTop返回指向第一个元素的指针,这将使其类型为void**。函数被声明为返回void*而不是DATATYPE*的事实使这一点令人困惑,但这是合法的,因为任何指针都可以转换为void*,包括双指针。

向队列添加元素时,会将其从Sensor_Time *投射到void*。稍后调用QueueTop时,您将获取返回值并将其强制转换为Sensor_Time *,这是错误的,因为它实际上是指向指针的指针。

要修复,您需要更改QueueTop以返回元素而不是指向元素的指针,或者更改您的调用代码以取消引用返回的指针。