kkontagion
kkontagion

Reputation: 516

"Dereferencing pointer to incomplete type", typedefs are ok

I'm trying to implement a hash table. I get the above error but AFAIK I've properly declared all my structs/typedefs. (I'm still learning C, sorry) The error occurs in test.c in my while loop, where I've put //ERROR. What's wrong?

test.c

#include "mentry.h"
#include "mlist.h"

int main() {
  FILE *fPtr = fopen("S.txt", "r");
  MList *ml = ml_create();

  MEntry *m2;
  int i = 1;
  while ((m2 = me_get(fPtr)) != NULL) {
    unsigned long int hash = me_hash(m2, ml->numbuckets); // ERROR HERE
    i++;
  }

  return 0;
}

mlist.c

#include "mentry.h"
#include "mlist.h"

#define NUMBUCKETS 3
#define BUCKETSIZE 5

typedef struct bucket {
  int size; // number of elements in this bucket
  MEntry *entries; // array of MEntries
} Bucket;

typedef struct mlist {
  int numbuckets; // number of buckets
  Bucket **buckets; // an array of Bucket pointers
} MList;

/* ml_create  - creates a new mailing list
              - returns pointer to start of mailing list*/
MList *ml_create(void) {
  MList *ml = malloc(sizeof(MList));

  ml->numbuckets = NUMBUCKETS; // random initial number
                               // will increment once a bucket is full

  // init Buckets
  int b;
  for (b=0; b<ml->numbuckets; b++) {
    Bucket *bk = malloc(sizeof(Bucket));
    bk->size = 0;
    bk->entries = calloc(BUCKETSIZE, sizeof(MEntry));
    ml->buckets[b] = bk;
  }

  return ml;
}

mlist.h

#ifndef _MLIST_H_
#define _MLIST_H_

#include "mentry.h"

typedef struct mlist MList;

/* ml_create  - creates a new mailing list
              - returns pointer to start of mailing list*/
MList *ml_create(void);

#endif /* _MLIST_H_ */

Upvotes: 0

Views: 1373

Answers (2)

R Sahu
R Sahu

Reputation: 206577

What's wrong?

You can use ml->numbuckets only if the complete definition of MList is visible at that line.

Since the complete definition of MList is visible only in mlist.c, you can access the members of the struct only in that file.

One way to do this would be to declare a function in mlist.h:

unsigned long int me_hash_list(MEntry* m1, MList* m2);

and define it in mlist.c as:

unsigned long int me_hash_list(MEntry* m1, MList* m2)
{
   return me_hash(m1, m2->numbuckets);
}

and then call me_hash_list from main.

while ((m2 = me_get(fPtr)) != NULL) {
  unsigned long int hash = me_hash_list(m2, ml);
  i++;
}

Upvotes: 1

dbush
dbush

Reputation: 223897

At the time you attempt to access ml->numbuckets in main, all it knows about the type of m1 is this:

typedef struct mlist MList;

It knows that MList is a structure type, but it knows nothing about what's in it.

You need to put the full definition in mlist.h:

#ifndef _MLIST_H_
#define _MLIST_H_

#include "mentry.h"

typedef struct mlist {
  int numbuckets; // number of buckets
  Bucket **buckets; // an array of Bucket pointers
} MList;

/* ml_create  - creates a new mailing list
              - returns pointer to start of mailing list*/
MList *ml_create(void);

#endif /* _MLIST_H_ */

Upvotes: 1

Related Questions