2011-01-30 10 views
5

皆さん、私はC言語の新人です。私の最初のプロジェクトでは、配列ベースのキューを実装する必要があります。 任意の種類のオブジェクトを保持できるようにキューを作成したいので、任意の型のオブジェクトへのvoidポインタを保持するQueueElement構造を作成しました。私はQueueElement構造体から 'position'と 'value'フィールドを読み取ることができないことを除いて、すべて動作していると思います。私はコンパイルしようとすると、次のエラーが表示されます。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

+1

QueueElement.hは、QueueElementStructのメンバーを定義すると言っていませんが、単にその存在を示唆しています。 QueueElement.hをインクルードすると、QueueElementStructという名前のstructがあり、その構成要素はありません。 QueueElement.cのみがQueueElementStructのメンバーを認識します。 –

+0

Logan、私はJerry'sと私のコードをコンパイルしてあなたのアドバイスを使いました。助けてくれてありがとう。 – Pooch

4

逆参照できるようにするには、void *を実際のタイプのポイントにキャストする必要があります。たとえば、intで始まっている場合は、アドレスを取得してキューに入れることができます。 intを見るには、int *にキャストする必要があります。実際のタイプを追跡することは、(通常は)重要ではありません(たとえば、コレクションに入れることができるすべてのタイプの列挙を作成し、そのうちの1つをコレクションの各アイテムに関連付けるなど)。

C++(ある例では)は、あるタイプのオブジェクトを特定のコレクションに入れることを選択する理由があります。

+0

私はそれをこの行のintにキャストしないでください:printf( "value:%d"、(int *)(f-> value)); – Pooch

+0

@Pooch:たぶん - 私はすべての200行(または何でも)のコードを確実にトレースすることはできませんでした。あなたのコメントにあるコードの一部は明らかに問題を抱えています - あなたは 'f-> value'を' int * 'にキャストしていますが、それを' '%d" '変換で' printf'に渡します。ポインタではなく 'int'を期待しています。おそらく '*(int *)(f-> value)'のようなものを意図していたでしょうか? –

+0

ありがとう、ジェリー、あなたのキャスト式が働いた! – Pooch

関連する問題