The following code gives me the following errors :
error: request for member ‘name’ in something not a structure or union
error: request for member ‘name’ in something not a structure or union
error: request for member ‘data’ in something not a structure or union
error: request for member ‘next’ in something not a structure or union
How could I fix it ?
Code is :
#define SIZE 5
typedef struct hashTable{
int data;
char *name;
struct hashTable *next;
} table;
int hash_function(int value)
{
return value % SIZE;
}
int insert(char *inFileName, table ***hashLinked)
{
FILE *inFile;
int val = -1;
char str[30];
int probe;
if ((inFile = fopen(inFileName, "r")) == NULL)
{
fprintf(stderr,"Error opening input file, %s\n", inFileName);
return -1;
}
while(fscanf(inFile,"%s %d",str,&val) == 2)
{
probe = hash_function(val);
if(hashLinked[probe] == NULL)
{
**hashLinked[probe] = malloc(sizeof(table));
**hashLinked[probe]->name = (char *)malloc((strlen(str) + 1) * sizeof(char*));
strcpy(**hashLinked[probe]->name,str);
**hashLinked[probe]->data = val;
**hashLinked[probe]->next = NULL;
}
else
{
table* hashLinkedNode = *hashLinked[probe];
while(hashLinkedNode->next!=NULL)
{
hashLinkedNode = hashLinkedNode->next;
}
hashLinkedNode->next = malloc(sizeof(table));
hashLinkedNode->next->name = (char *)malloc((strlen(str) + 1) * sizeof(char*));
strcpy(hashLinkedNode->next->name,str);
hashLinkedNode->next->data = val;
hashLinkedNode->next->next = NULL;
}
}
fclose(inFile);
return 0;
}
void printList(BookNode *hd)
{
for ( ; hd != NULL; hd = hd->next)
{
printf("[%s,%d]", hd->name, hd->isbn);
if (hd->next)
printf(" -> ");
}
printf("\n");
}
void printHashTable(BookNode **temp)
{
BookNode *tmp = NULL;
int i;
for(i=0;i<SIZE;i++)
{
tmp = temp[i];
while(tmp)
{
printf("%s %d",tmp->name, tmp->isbn);
tmp=tmp->next;
}
}
}
int main(int argc, char *argv[])
{
table **hashLinked[SIZE];
insert(argv[1],&hashLinked);
printHashTable(**hashLinked);
return 0;
}
One problem is that you call
insertwith something other than the type you declared it with,hashLinkedis an array of pointers to pointers totable, so&hashLinkedis a pointer to an array of pointers to pointers totable, butinsertis declared to take a pointer to pointer to pointer totable. I’m less than confident that I really figured out what you intended to do, but what seems to be reasonable is that you want fewer levels of indirection. I believe the reason for passing&hashLinkedis that you wanthashLinkedto be modified ininsert, but that is already done by passinghashLinkeditself, you needn’t pass its address. That would make the passed type compatible with the declared type, since as a function argument,hashLinkedbecomes a pointer to its first element, atable ***.Then you use inconsistent indirection counts in
insert, and get the precedence of*and->wrong, which causes the “request for member in something that isn’t a struct or union” errors.**hashLinked[probe]->nameis parsed**(hashLinked[probe]->name), so tries to access thenamemember of atable *and then dereference that twice. With the parameter typetable ***, the correct access would be(*hashLinked[probe])->name, get atable **perhashLinked[probe], dereference that once to get atable *and access its (pointee)membername. However, you checkif (hashLinked[probe] == NULL), and if sowhich is a guaranteed null pointer dereferencing. By the check and the following code, I believe that you actually want to have a parameter type of
table **, thehashLinkedparameter being an array of linked lists oftables, which makes the code far easier to follow. Filling in aBookNodetype and adapting a few variables and parameters, I arrive atwhich compiles warning-free and looks like it might do what you intended.