2011-01-30 75 views
5

嗨,大家好,我是C的新手,对于我的第一个项目,我需要实现一个基于数组的队列。 我希望我的队列能够容纳任何类型的对象,所以我创建了一个QueueElement结构来存放指向任何类型对象的void指针。我认为所有工作,除了我无法读取我的QueueElement结构中的'位置'和'值'字段。当我尝试编译时,出现以下错误。C Dereference void * pointer

错误:

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

我敢肯定,我只是不投正常。任何帮助表示赞赏。再次

感谢, 普茨

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

#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

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

回答

6

QueueElementStruct的定义必须是在Runnable.c可见能够访问它的领域。您可以将QueueElementStruct放入您可以包含在Runnable.cQueueElement.c中的标题。或者,您可以使用您的GetPosition函数并添加GetValue函数,并使用Runnable.c中的函数代替直接字段访问。

+0

Runnable.c包含Queue.h,后者又包含QueueElement.h这样的链接是否包含工作? – Pooch 2011-01-30 02:45:48

+1

它的确如此,但QueueElement.h并没有说定义了QueueElementStruct的成员,而只是表明它的存在。如果我包含QueueElement.h,我只知道有一个名为QueueElementStruct的结构,而不是它的组成部分。只有QueueElement.c知道QueueElementStruct的成员是什么。 – 2011-01-30 02:54:10

4

您必须将void *重新指向“真实”类型,然后才能对其进行解引用。例如,如果您从int开始,则可以取其地址,并将其放入队列中。要查看int,您必须将其重新转换为int *。跟踪真实类型可以(通常是)非平凡的(例如,创建要放入集合中的所有类型的枚举,并将其中的一个与集合中的每个项目关联)。

有一个原因,C++(例如)选择只将一种类型的对象放入任何给定的集合中。