2011-01-30 74 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++(例如)選擇只將一種類型的對象放入任何給定的集合中。