2011-01-30 25 views
5

Hola chicos, soy nuevo en C y para mi primer proyecto necesito implementar una cola basada en matrices. Quiero que mi cola pueda contener cualquier tipo de objeto, así que creé una estructura QueueElement para mantener un puntero vacío a un objeto de cualquier tipo. Creo que todo funciona, excepto que no puedo leer los campos 'posición' y 'valor' de mi estructura QueueElement. Me aparece el siguiente error cuando intento compilar.C Dereference void * puntero

error:

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

Estoy bastante seguro de que no estoy echando correctamente. Cualquier ayuda es apreciada.

Gracias de nuevo, 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

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

Respuesta

6

La definición de QueueElementStruct tiene que ser visible en Runnable.c para poder acceder a los campos de la misma. Puede poner QueueElementStruct en un encabezado que puede incluir en Runnable.c y QueueElement.c. Alternativamente, puede usar su función GetPosition y agregar una función GetValue y usarlas de Runnable.c en lugar de acceso directo al campo.

+0

Runnable.c incluye Queue.h que a su vez incluye QueueElement.h ¿Incluye este enlace de trabajo? – Pooch

+1

Sí, pero QueueElement.h no define los miembros de QueueElementStruct, simplemente sugiere su existencia. Si incluyo QueueElement.h, todo lo que sé es que hay una estructura llamada QueueElementStruct, no sus constituyentes. Solo QueueElement.c sabe cuáles son los miembros de QueueElementStruct. –

+0

Logan, utilicé su consejo junto con Jerry's y mi código compilado. Gracias por la ayuda chicos. – Pooch

4

Tiene que convertir el void * de nuevo en punto al tipo "real" antes de poder desreferenciarlo. Por ejemplo, si comienza con un int, puede tomar su dirección y colocarla en la cola. Para mirar el int, tendrá que devolverlo al int *. Hacer un seguimiento del tipo real puede ser (por lo general) no trivial (por ejemplo, crear una enumeración de todos los tipos que desee poner en la colección y asociar uno de ellos con cada elemento de la colección).

Hay una razón por la que C++ (por ejemplo) opta por solo poner un tipo de objeto en una colección dada.

+0

no lo vuelvo a convertir en una int en esta línea: printf ("valor:% d", (int *) (f-> valor)); – Pooch

+0

@Pooch: Tal vez - Me temo que no he rastreado las 200 (o lo que sea) líneas de código para estar seguro.OTOH, el bit de código en tu comentario claramente tiene un problema: estás convirtiendo 'f-> value' en' int * ', pero luego lo pasas a' printf' con una ''% d "' conversión, que espera un 'int', no un puntero. Tal vez intentaste algo como '* (int *) (f-> value)'? –

+0

Gracias Jerry, tu expresión de elenco funcionó! – Pooch