This is my first post here so I thank everyone in advance for any and all help.
I'm having an issue with disappearing information. The program is supposed to read in book titles and library ID numbers from a file, create a hash table of linked lists where each node contains a book struct that holds the title of the book and another linked list with the library IDs where the book can be found. At this point I am just trying to fill the hash table but for some reason my title values are disappearing. The file format is shown below:
2345, Old Man and the Sea
567434, Harry Potter
1233, The Art of Learning
etc...
I have
typedef NodeStruct {void* data; NodePtr prev; NodePtr next;} NodeStruct;
typedef NodeStruct* NodePtr;
typedef ListStruct {NodePtr first; NodePtr last; NodePtr current; } ListStruct;
typedef ListStruct* ListHndl;
typedef BookStruct {char* title; ListHndl lib; } BookStruct;
typedef BookStruct* BookHndl;
FILE *fileptr;
int numlines;
int numslots;
int i;
int index;
NodePtr fillnode;
int main(int argc, char *argv[]) {
fileptr = fopen(argv[1], "r");
if (!fileptr) {
printf("Error: cannot open file\n");
return 1;
}
int *libID = malloc(sizeof(int));
printf("(main) libID: %p\n", libID);
fscanf(fileptr, "%d %d", &numlines, &numslots);
printf("(main) numlines: %d numslots: %d\n", numlines, numslots);
ListHndl *H = calloc(numslots, sizeof(ListHndl));
printf("(main) calloc iterated\n");
for (i = 0; i < numlines; i++) {
printf("*************LOOP #%d*************\n", i);
char *title = malloc(sizeof(char) * 50);
if (fscanf(fileptr, "%d%*c%*c%[^\n]", libID, title) == 0) {
printf("Error: incorrect # of keys\n");
return 1;
}
printf("(main) book: %s ID: %d\n", title, *libID);
index = hash(title, numslots);
printf("(main) index: %d\n", index);
printf("(main) hash[index]: %p\n", H[index]);
if (H[index] == NULL) {
H[index] = newList();
printf("(main_if_H_NULL) hash[index]: %p\n", H[index]);
BookHndl B = newBook(title, libID);
printf("(main_if_H_NULL) BookHndl B: %p\n", B);
insertAtFront(H[index],(void *) B);
printf("(main_if_H_NULL) H[index] title: %s ID: %d\n", ((BookHndl) H[index]->first->data)->title,
*((int *) ((BookHndl) H[index]->first->data)->lib->first->data));
}
printAll(H, numslots);
NodePtr S = searchTitle(H[index], title);
printf("(main) NodePtr S: %p\n", S);
if (S == NULL) {
BookHndl B = newBook(title, libID);
insertAtBack(H[index], (void *) B);
printf("(main_if_!S) inserted book\n");
} else {
printf("(main_if_S)\n");
ListHndl idL = ((BookHndl) S->data)->lib;
if (searchID(idL, libID) == 0) {
insertAtBack(idL, (void *) libID);
printf("(main_if_S) inserted libID\n");
}
}
free((char *) title);
free((NodePtr) S);
printAll(H, numslots);
printf("hash[%d]: %s in library # %d\n", index, title, *libID);
}
return 1;
}
there are actually four fscanf arguments %d for libID, %*c to jump over ",", another %*c to jump over the " ", and %[^/n] to read the title until a newline is read. The print statement shortly after confirms correct values in both libID and title. At printAll(H, numslots), all values are present, upon return of NodePtr S = searchTitle(H[index], title) the title is gone. Below are my newBook and searchTitle functions
BookHndl newBook(char* str, int* ID) {
BookHndl B = malloc(sizeof(BookStruct));
/*B->title = malloc(sizeof(char) * 50);*/
B->title = strdup(str);
printf("(newBook) B->title = %s\n", B->title);
B->lib = newList();
printf("(newBook) B->lib = %p\n", B->lib);
insertAtFront(B->lib, (void *) ID);
printf("(newBook) B->lib->first = %d\n", *((int *)B->lib->first->data));
return B;
}
NodePtr searchTitle(ListHndl L, char* key) {
assert(L != NULL);
if (isEmpty(L)) {
printf("Book list empty\n");
return NULL;
} else {
L->current = L->first;
printf("(searchTitle) ListHndl L = %p, L->first = %p, L->first->data = %p\n", L, L->first, (BookHndl) L->first->data);
while (L->current != NULL) {
BookHndl B = malloc(sizeof(BookStruct));
B = (BookHndl) L->current->data;
printf("(searchTitle) bookhandle B = %p\n", B);
printf("(searchTitle) B->title = %s\n B->ID = %d\n", B->title, *((int *) B->lib->first->data));
if (strcmp(B->title, key) == 0) {
free(B);
return L->current;
}
free(B);
L->current = L->current->next;
}
}
return NULL;
}
This code is broken.
BookHndl B = malloc(sizeof(BookStruct));
B = (BookHndl) L->current->data;
// ...
free(B);
This will leak a chunk of memory and then free something out of your node structure. Fix this, and the problem might go away.