2

I'm new to C been at it about two weeks, hitting a few problems with linked lists and hash tables. The compilier is throwing a few errors:

I've tried to mark these in the source code.

finddupl.c: In function 'main':

finddupl.c:35:5: warning: assignment from incompatible pointer type

finddupl.c:37:3: warning: passing argument 1 of 'ml_lookup' from incompatible pointer type

mlist.h:19:9: note: expected 'struct MList *' but argument is of type 'struct MList *'

mlist.c: In function 'ml_lookup':

mlist.c:63:37: warning: assignment from incompatible pointer type

mlist.c: In function 'ml_add':

mlist.c:78:9: error: request for member 'hashtable' in something not a structure or union

mlist.c:90:12: warning: assignment from incompatible pointer type

Can anyone guide me in the right direction here, I've been at this for a few hours

Not loving C so far :p

I've left out the mentry.c and the c file with the main function, I've tested both of these before I tried to write the hash table.

Mentry.h

#ifndef _MENTRY_INCLUDED_
#define _MENTRY_INCLUDED_

#include <stdio.h>

typedef struct mentry {
char *surname;
int house_number;
char *postcode;
char *full_address;
} MEntry;

/* me_get returns the next file entry, or NULL if end of file*/
MEntry *me_get(FILE *fd);

/* me_hash computes a hash of the MEntry, mod size */
unsigned long me_hash(MEntry *me, unsigned long size);

/* me_print prints the full address on fd */
void me_print(MEntry *me, FILE *fd);

/* me_compare compares two mail entries, returning <0, 0, >0 if
* me1<me2, me1==me2, me1>me2
*/
int me_compare(MEntry *me1, MEntry *me2);

#endif /* _MENTRY_INCLUDED_ */

mlist.h

#ifndef _MLIST_INCLUDED_
#define _MLIST_INCLUDED_

#include "mentry.h"

typedef struct mlist MList;

extern int ml_verbose;      /* if true, prints diagnostics on stderr */

/* ml_create - created a new mailing list */
struct MList *ml_create(void);

/* ml_add - adds a new MEntry to the list;
 * returns 1 if successful, 0 if error (malloc)
 * returns 1 if it is a duplicate */
int ml_add(MList **ml, MEntry *me);

/* ml_lookup - looks for MEntry in the list, returns matching entry or NULL */
MEntry *ml_lookup(struct MList *ml, MEntry *me);

#endif /* _MLIST_INCLUDED_ */

mlist.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mentry.h"
#include "mlist.h"
#define HASHSIZE 101


struct Mlist_node{
 MEntry *me;
MEntry *next;
int size;
};

struct Mlist_head{
struct Mlist_node *head;
struct Mlist_node *tail;
};

struct MList{
int size;
struct Mlist_head hashtable[HASHSIZE];
};



struct MList *ml_create(void){

struct MList *m;
struct Mlist_head *h;
int i;

if ((m = ( struct MList *)malloc(sizeof(struct MList))) != NULL){
    if ((h = (struct Mlist_head *)malloc(sizeof(struct Mlist_head))) != NULL) { 
        for (i = 0; i < HASHSIZE; i++) {
            h = &(m->hashtable[i]);
            h->head = NULL;
            h->tail = NULL;
        }
        printf("worked");
        return m;
}
}




printf("fail");
return NULL;
}




MEntry *ml_lookup(struct MList *ml, MEntry *me){
struct Mlist_node *mn;
struct Mlist_head *mh;
if ((mn = (struct Mlist_node *)malloc(sizeof(struct Mlist_node))) != NULL) {    
if ((mh = (struct Mlist_head *)malloc(sizeof(struct Mlist_head))) != NULL) {    
    unsigned hashval = me_hash(me,HASHSIZE);
    printf("%d",hashval);
mh=&(ml->hashtable[hashval]);
for (mn = mh->head; mn != NULL; mn = mn->next) //LINE 63 ERROR
    if (me_compare(mn->me, me) == 0)
        return me; /* found */
        }
        }
return NULL;

}

int ml_add(MList **ml, MEntry *me){

unsigned hashval;
struct Mlist_head *mh;
struct Mlist_node *mn;
hashval = me_hash(me,HASHSIZE);
mh = ml->hashtable[hashval];   //LINE 78 ERROR

if ((mn = (struct Mlist_node *)malloc(sizeof(struct Mlist_node))) != NULL){
    mn->me=me;
    if(mh->head==NULL){
        mh->head=mn;
        mh->tail=mn;
        mn->next=NULL;
    }
    else{
        mn = mh->tail;
        mn->next=me;
        mh->tail=me;   /LINE 90 ERROR

    }
    return 1;
}
else{
    printf("failed to allocate memory");
    return 0;
}

/* not found */
}
Samir Talwar
  • 14,220
  • 3
  • 41
  • 65
bond425
  • 1,077
  • 1
  • 7
  • 12
  • Please don't cast the return value from `malloc`: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Fred Foo May 02 '11 at 19:45

1 Answers1

0

Look into how you're forward declaring MList in mlist.h. You use the syntax

 typedef struct mlist MList;

This looks a little off to me. You're declaring a type of name MList. Note that with the above style of declaration, the compiler expects to see "struct mlist" or just the type name's MList when referring to this struct. (This question may be helpful to you). However later on you definen a struct MList as follows:

struct MList{
int size;
struct Mlist_head hashtable[HASHSIZE];
};

Which makes the compiler expect afterwords to see things referred to with "struct MList". But in your fwd declaration, you just said that plain old "MList" without the struct is ok. The compiler may or may not be able to make sense of this confusion between the fwd declaration and your definition. Its made worse in that one is a tag name of the struct and the other is the struct's canonical name. This kind of thing makes my spidy sense tingle that something could be off and causing confusion between you and the compiler.

I would just change how you forward declare to be consistent with how Mlist is used and see if that helps you. To do this change the above line to:

 struct MList;

(then notice in mlist.h how you inconsistently use the struct keyword when referring to MList. Sometimes you do and sometimes you don't. this may also be causing problems w/ confusing your compiler. If you change to the above fwd declaration, use struct MList, not just MList)

In other news, for:

mlist.c:63:37: warning: assignment from incompatible pointer type

You're assigning a MEntry to a MNode, which are of different types, so I would expect you to get the warning you're getting.

Community
  • 1
  • 1
Doug T.
  • 64,223
  • 27
  • 138
  • 202