Одна проблема заключается в том, что вы вызываете insert
с чем-то отличным от типа, который вы объявили,
table **hashLinked[SIZE];
insert(argv[1],&hashLinked);
hashLinked
- это массив указателей на указатели на table
, поэтому &hashLinked
- это указатель на массив указателей на указатели на table
, но объявлено, что insert
принимает указатель на указатель на указатель на table
. Я менее чем уверен, что действительно понял, что вы намеревались сделать, но что кажется разумным, так это то, что вам нужно меньше уровней косвенности. Я считаю, что причина передачи &hashLinked
состоит в том, что вы хотите, чтобы hashLinked
был изменен в insert
, но это уже делается путем передачи самого hashLinked
, вам не нужно передавать его адрес. Это сделало бы передаваемый тип совместимым с объявленным типом, поскольку в качестве аргумента функции hashLinked
становится указателем на его первый элемент, table ***
.
Затем вы используете непоследовательные значения косвенности в insert
и неправильно получаете приоритет *
и ->
, что приводит к ошибкам «запрос члена в чем-то, что не является структурой или объединением». **hashLinked[probe]->name
анализируется **(hashLinked[probe]->name)
, поэтому пытается получить доступ к name
члену table *
и затем разыменовывать его дважды. С параметром типа table ***
правильный доступ будет (*hashLinked[probe])->name
, получим table **
за hashLinked[probe]
, разыменование, чтобы один раз получить table *
и получить доступ к его (pointee) члену name
. Тем не менее, вы проверяете if (hashLinked[probe] == NULL)
, и если так
**hashLinked[probe] = malloc(sizeof(table));
, что является гарантированной разыменовкой нулевого указателя. Благодаря проверке и следующему коду, я считаю, что вы действительно хотите иметь тип параметра table **
, параметр hashLinked
представляет собой массив связанных списков table
s, что значительно упрощает выполнение кода. Заполняя тип BookNode
и адаптируя несколько переменных и параметров, я получаю
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define SIZE 5
typedef struct hashTable {
int data;
char *name;
struct hashTable *next;
} table;
typedef struct book {
int isbn;
char *name;
struct book *next;
} BookNode;
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(table **temp)
{
table *tmp = NULL;
int i;
for(i = 0; i < SIZE; i++)
{
tmp = temp[i];
while(tmp)
{
printf("%s %d",tmp->name, tmp->data);
tmp = tmp->next;
}
}
}
int main(int argc, char *argv[])
{
if (argc < 2)
return -1;
table *hashLinked[SIZE];
insert(argv[1],hashLinked);
printHashTable(hashLinked);
return 0;
}
, который компилирует без предупреждений и выглядит так, как будто он может делать то, что вы хотели.