简体   繁体   English

C 取消引用 void* 指针

[英]C Dereference void* pointer

I am new to C and for my first project I need to implement an array based queue.我是 C 新手,对于我的第一个项目,我需要实现一个基于数组的队列。

I want my queue to be able to hold any kind of object so I created a QueueElement structure to hold a void pointer to an object of any type.我希望我的队列能够保存任何类型的对象,因此我创建了一个 QueueElement 结构来保存指向任何类型对象的 void 指针。 I think all is working except I am unable to read the 'position' and 'value' fields from my QueueElement struct.我认为除了我无法从我的 QueueElement 结构中读取“位置”和“值”字段之外,一切都在工作。 I get the following error when I try to compile.当我尝试编译时出现以下错误。

Error:错误:

Runnable.c: In function `main':
Runnable.c:10: error: dereferencing pointer to incomplete type
Runnable.c:11: error: dereferencing pointer to incomplete type

I'm pretty sure I'm just not casting properly.我很确定我只是没有正确投射。 Any help is appreciated.任何帮助表示赞赏。

Thanks again, Pooch再次感谢,波奇

Runnable.c可运行文件

   #include <stdio.h>
    #include "Queue.h"
    
    int main(void) {
            int i = 9;
            Queue q = CreateQueue();
            QueueElement e = CreateQueueElement(&i);
            Enqueue(q, e);
            QueueElement f = Dequeue(q);


            /* PROBLEM IS HERE */
            printf("position: %d", f->position);
            printf("value: %d", (int *)(f->value));
            DestroyQueue(q);
            return 0;
    }

Queue.h队列.h

#ifndef QUEUE_H
#define QUEUE_H

#include "QueueElement.h"

typedef struct QueueStruct *Queue;

Queue CreateQueue(void);

void DestroyQueue(Queue q);

void Enqueue(Queue q, QueueElement e);

QueueElement Dequeue(Queue q);

#endif

Queue.c队列文件

#include "QueueElement.h"
#include "Queue.h"

#define QUEUE_SIZE 10

struct QueueStruct {
        QueueElement contents[QUEUE_SIZE];
        int size;
};

Queue CreateQueue(void) {
        Queue q = malloc(sizeof(struct QueueStruct));
        q->size = 0;
        return q;
}

void DestroyQueue(Queue q) {
        int i;
        for(i = 0; i < q->size; i++) {
                free(q->contents[i]);
        }
        free(q);
}

void Enqueue(Queue q, QueueElement e) {
        if (q->size < QUEUE_SIZE) {
                q->contents[q->size++] = e;
        }
}

QueueElement Dequeue(Queue q) {
        if (q->size > 0) {
                return q->contents[--q->size];
        }
        return;
}

QueueElement.h队列元素.h

#ifndef QUEUE_ELEMENT_H
#define QUEUE_ELEMENT_H

typedef struct QueueElementStruct *QueueElement;

QueueElement CreateQueueElement(void *v);

void DestroyQueueElement(QueueElement e);

int GetPosition(QueueElement e);

#endif

QueueElement.c队列元素

#include <stdio.h>
#include "QueueElement.h"

struct QueueElementStruct {
        int position;
        void *value;
};

QueueElement CreateQueueElement(void *v) {
        QueueElement e = malloc(sizeof(struct QueueElementStruct));
        e->position = 0;
        e->value = v;
        return e;
}

void DestroyQueueElement(QueueElement e) {
        free(e);
}

int GetPosition(QueueElement e) {
        return e->position;
}

The definition of QueueElementStruct has to be visible in Runnable.c to be able to access fields of it. QueueElementStruct的定义必须在 Runnable.c 中可见才能访问它的字段。 You can put QueueElementStruct into a header that you can include in Runnable.c and QueueElement.c .您可以将QueueElementStruct放入可以包含在Runnable.cQueueElement.c的标头中。 Alternatively, you can use your GetPosition function and add a GetValue function and use those from Runnable.c instead of direct field access.或者,您可以使用GetPosition函数并添加GetValue函数并使用Runnable.c函数而不是直接字段访问。

You have to cast the void * back to point at the "real" type before you can dereference it.在取消引用它之前,您必须将void *回指向“真实”类型。 eg, if you start with an int , you can take its address, and put it in the queue.例如,如果您以int开头,则可以获取其地址,并将其放入队列中。 To look at the int , you'll have to cast it back to int * .要查看int ,您必须将其转换回int * Keeping track of the real type can be (usually is) non-trivial (eg, creating an enumeration of all types you want to be able to put in the collection and associating one of those with each item in the collection).跟踪真实类型可能(通常是)非常重要(例如,创建您希望能够放入集合中的所有类型的枚举,并将这些类型之一与集合中的每个项目相关联)。

There's a reason that C++ (for one example) opts for only putting one type of object into any given collection. C++(例如)选择只将一种类型的对象放入任何给定集合是有原因的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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