segmentation fault after free-ing node in hashtable - c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define size 9900
int count = 1;
struct membership {
char name[100];
char gender[100];
char code[100];
int age;
int weight;
struct membership* next;
}*table[size];
typedef struct membership member;
member *newMember(char name[], char gender[], char code[], int age, int weight){
member *node = (member*)malloc(sizeof(member));
strcpy(node->name, name);
strcpy(node->gender, gender);
strcpy(node->code, code);
node->age = age;
node->weight = weight;
node->next = NULL;
return node;
}
int asciiSum(char str[]){
int sum = 0;
for(int i = 0; str[i] != '\0'; i++){
sum += str[i];
}
return sum;
}
int hash(char code[]){
return asciiSum(code)%size;
}
// insert recursive
member *insertRec(member *curr, char name[], char gender[], char code[], int age, int weight){
if (!curr){
return newMember(name, gender, code, age, weight);
}
curr->next = insertRec(curr->next, name, gender, code, age, weight);
return curr;
}
// insert biasa
void insert(char name[], char gender[], char code[], int age, int weight){
int key = hash(code);
table[key] = insertRec(table[key], name, gender, code, age, weight);
}
void viewMember(){
printf("| %-5s | %-20s | %-20s | %-20s | %-20s | %-15s |\n",
"no", "member name", "member age", "member weight", "member gender", "member code");
int j = 0;
for (int i = 0; i < size; i++) {
member *curr = table[i];
while (curr) {
printf("| %-5d | %-20s | %-20d | %-20d | %-20s | %-15s |\n",
++j, curr->name, curr->age, curr->weight, curr->gender, curr->code);
curr = curr->next;
}
}
}
member *searchRec(member *curr, char *code){
if (!curr) return NULL;
if(!strcmp(curr->code, code))return curr;
return searchRec(curr->next, code);
}
member *deleteRec(member *curr, char *code){
if (!curr) return NULL;
if (!strcmp(curr->code, code)){
free(curr);
return curr->next;
}
curr->next = deleteRec(curr->next, code);
return curr;
}
void deleteProduct(char *code){
int key = hash(code);
member *node = searchRec(table[key], code);
if (!node) {
printf("%s not found\n", code);
return;
}
printf("Deleted %s\n", node->name);
table[key] = deleteRec(table[key], code);
}
int main(){
insert("tono", "male", "61TOM102", 21, 40);
insert("tini", "female", "61TIF102", 21, 40);
insert("didi", "male", "102DIM102", 21, 40);
deleteProduct("61TOM102");
viewMember();
return 0;
}
The code above will produce zsh: segmentation fault.
What i expected : tono node got freed and the array got printed as normal but without tono
What actually resulted : zsh: segmentation fault
i think the error is either in deleteRec function or viewMember function.
i think after i free(curr) it somehow still there but as an invalid memory ?
i'm really stumped, can someone give me a hint ?
Thank you in advance
PS. when i try running the code on online compiler there's no problem, is the problem with my hardware ?

Related

Bus error while simply integer scanf sequence in C program

I have to take integer inputs and end the while loop if input is -1 in the following format in C:
111 1 1
111 1 1
111 1 1
-1
My code get bus error after 3rd scanf in the main function (end of the code). I know this is about white spaces but i have no idea to solve it. I am testing on MacBook with M1 if it is important. Btw print("break")s for just testing, i don't want to any junk print or scan.
#include <stdio.h>
#include <stdlib.h>
struct employee{
int ID;
int freeAt;
int totalTime;
struct employee *next;
};
struct customer{
int ID;
int startTime;
int processTime;
int waitingTime;
int helper;
struct customer *front;
struct customer *rear;
struct customer *next;
};
typedef struct employee employee;
typedef struct customer customer;
void new_employer(employee *top, int id){ //Insert employees by id
employee *ptr;
ptr = (employee*)malloc(sizeof(employee));
ptr->ID = id;
ptr->freeAt = 0;
ptr->totalTime = 0;
if (top == NULL){
ptr->next = NULL;
top = ptr;
}
else{
ptr->next = top;
top = ptr;
}
}
void help_customer(customer *c, employee *top){ //Match customer with suitable employee
employee *ptr;
ptr = (employee*)malloc(sizeof(employee));
ptr = top;
if (top==NULL){
c->startTime = c->startTime + 1;
c->waitingTime++;
help_customer(c,ptr);
}
if(c->startTime>=top->freeAt){
c->helper = top->ID;
top->freeAt = c->startTime + c->processTime;
top->totalTime = top->totalTime + c->processTime;
}
else{
help_customer(c, top->next);
}
}
void new_customer(customer *c, employee *top, int id, int start, int process){ //New customer
customer *ptr;
ptr = (customer*)malloc(sizeof(customer));
ptr->ID = id;
ptr->startTime = start;
ptr->processTime = process;
ptr->waitingTime = 0;
help_customer(ptr,top);
if (c->front == NULL){
c->front = ptr;
c->rear = ptr;
c->next = NULL;
}
else{
c->rear->next = ptr;
c->rear = ptr;
c->rear->next = NULL;
}
}
void customerStats(customer *c){ //Printing customer stats at the end of the transactions
customer *ptr;
ptr = (customer*)malloc(sizeof(customer));
ptr = c->front;
if(ptr == NULL){
printf("\nQUEUE IS EMPTY");
}
else{
printf("\n");
while (ptr!=c->rear){
printf("%d ", ptr->ID);
printf("%d ", ptr->helper);
printf("%d ", ptr->startTime);
printf("%d ", ptr->processTime);
printf("%d\n", ptr->waitingTime);
ptr = ptr->next;
}
printf("%d ", ptr->ID);
printf("%d ", ptr->helper);
printf("%d ", ptr->startTime);
printf("%d ", ptr->processTime);
printf("%d\n", ptr->waitingTime);
}
}
void employeeStats(employee *top){ //Printing employee stats at the end of the transactions
employee *ptr;
ptr = (employee*)malloc(sizeof(employee));
ptr = top;
if (top==NULL){
printf("\nSTACK IS EMPTY");
}
else{
while (ptr!=NULL){
printf("%d ", ptr->ID);
printf("%d\n", ptr->totalTime);
ptr = ptr->next;
}
}
}
int main(){
employee *e;
for(int i=1;i>7;i++){
new_employer(e,i);
}
customer *c;
int id;
int start;
int process;
while(1){ //********I GET BUS ERROR HERE ON 3RD SCANF**************
scanf("%d", &id);
printf("break1");
if (id==-1){
break;
}
scanf("%d", &start);
printf("break2");
scanf("%d", &process);
printf("break3");
new_customer(c,e,id,start,process);
}
customerStats(c);
employeeStats(e);
}
This is the terminal:
111
break11
break21
zsh: bus error ./main
It helps if you write minimal code to begin with, and get that working before adding more.
Here's a partial correction that shows why you are getting undefined behaviour (crashing). Read each line and understand why and how it differs from your code. Once that is understood, you can (cautiously, step-by-step) add one more element at a time and test, test, test as you build up toward your objective.
typedef struct employee {
int ID;
int freeAt;
int totalTime;
struct employee *next;
} employee_t;
employee_t *new_employeEEEE( employee_t *top, int id ) { //Insert employees by id
employee_t *ptr = (employee_t*)calloc( 1, sizeof(*ptr) ); // use calloc()
// Omitting check of calloc failing
ptr->ID = id;
ptr->next = top; // reverse sequence, but at least it works...
return ptr;
}
int main() {
employee_t *e = NULL;
// for( int i=1; i > 7;i++ ) !!!!
for( int i = 1; i < 7; i++ )
e = new_employeEEEE( e, i );
i = 1;
for( employee *p = e; p; p = p->next )
printf( "emp #%d has id: %d\n", i++, p->ID );
return 0;
}
Output:
emp #1 has id: 6
emp #2 has id: 5
emp #3 has id: 4
emp #4 has id: 3
emp #5 has id: 2
emp #6 has id: 1

Something wrong with add func

When I print the linked list countryName value always stay with the last string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct usa_primaries * ptr;
typedef struct primariesDate{
int month;
int day;
int hour;
}primariesDate;
typedef struct usa_primaries{
primariesDate date;
char *countryName;
int isOpen;
ptr next;
}usa_primaries;
void add (int month, int day, int hour, char *country, int isOpen, ptr *head) {
ptr t;
t = (ptr) malloc(sizeof(usa_primaries));
t->date.month = month;
t->date.day = day;
t->date.hour = hour;
t->countryName = (char *) malloc(strlen(country)+1);
strcpy(t->countryName, country);
t->isOpen = isOpen;
if(!(*head)) {
t->next = NULL;
*head = t;
}
else {
t->next = *head;
*head = t;
}
Below is the main function, I'm trying to print only countryName details but what I see is only the last value that is inserted. for example: scanf: test1, test2 the output is: test2 test2
int main() {
ptr head = NULL;
int month, day, hour, isopen;
char country[20];
while (scanf("%d %d %d %s %d", &month, &day, &hour, country, &isopen) != EOF) {
add(month, day, hour, country, isopen, &head);
}
ptr print = head;
while (print) {
printf("\n %s ", head->countryName);
print = print->next;
}
free(head);
return 0;
}
while (print) {
printf("\n %s ", head->countryName);
// ^^^^
print = print->next;
}
You print only the head in the loop. You should print the current node:
while (print) {
printf("\n %s ", print->countryName);
// ^^^^^
print = print->next;
}

Adding struct pointer to a pointer array

I have a problem and I really dont know what to do.
I'am trying to insert "new students" to an student-array. The array contains pointers to the created structs. Can somebody find the error? It adds the student-structs to the array but especially the printing doesnt work.
It would be really helpful, if somebody could help me. :) PS: You can just copy the code.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH 10
typedef struct student
{
unsigned int matnr;
char *name;
struct student *next_student;
} Student;
Student **hash_tabelle[MAX_HASH];
void insert_student (unsigned int matnr, char *name)
{
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(sizeof(*name)+1);
neuer_student->matnr = matnr;
strcpy(neuer_student->name, name);
neuer_student->next_student = NULL;
// Index im Hash-Array ermitteln
int hash_index = matnr % 10;
if(hash_tabelle[hash_index] == NULL)
{
neuer_student->next_student = hash_tabelle[hash_index];
hash_tabelle[hash_index] = neuer_student;
}
else
{
while(*hash_tabelle[hash_index] != NULL && (((*hash_tabelle[hash_index])->matnr - neuer_student->matnr) <= 0))
hash_tabelle[hash_index] = &(*hash_tabelle[hash_index])->next_student;
neuer_student->next_student = *hash_tabelle[hash_index];
*hash_tabelle[hash_index] = neuer_student;
}
}
void print_hash_tabelle()
{
for(int i = 0; i != MAX_HASH - 1; i++){
printf("%d)\t", i);
hash_tabelle[i] = &(*hash_tabelle[i])->next_student;
for(; hash_tabelle[i] != NULL; hash_tabelle[i] = &(*hash_tabelle[i])->next_student){
printf("%s (%d)", (&(*hash_tabelle[i])->name), (&(*hash_tabelle[i])->matnr));
}
printf("\t");
}
}
int main()
{
unsigned int matnr;
char name[100];
do
{
printf("Matrikelnummer:\t");
scanf("%d", &matnr);
fflush(stdin);
getchar(); // um das \n aus dem Puffer zu kriegen und rauszuschmeißen
printf("Name:\t\t");
fgets(name, 30, stdin);
insert_student(matnr, name);
}
while (matnr != 0);
print_hash_tabelle();
return 0;
}
Using a hash table is so simple... No need to use dereferencing for a fixed-size array of linked-list pointers.
Step 1 - a hash table is a array of linked-list pointers.
As #BLUEPIXY suggests:
Student *hash_tabelle[MAX_HASH];
Step 2 - to allocate and free each linked-list, initialize each item to NULL.
Otherwise, if(hash_tabelle[hash_index] == NULL) is Undefined
behavior in the function insert_student().
void hash_init()
{
for(int i=0;i<MAX_HASH;i++) {
hash_tabelle[MAX_HASH]=NULL;
}
}
Step 3 - allocate enough char to store the char *name to insert_student().
As # WhozCraig suggests, use strlen().
void insert_student (unsigned int matnr, char *name)
{
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(strlen(name)+1);
neuer_student->matnr = matnr;
strcpy(neuer_student->name, name);
neuer_student->next_student = NULL;
Step 4 - add the neuer_student in the hash_tabelle[] (function insert_student())
Warning: the index shall be included in the size of the array
[0..MAX_HASH[. (using 10 instead of MAX_HASH could become a bug).
int hash_index = matnr % MAX_HASH;
When the hash_tabelle[hash_index] is NULL, simple store the
neuer_student. No need to modify neuer_student->next_student.
if(hash_tabelle[hash_index] == NULL)
{
hash_tabelle[hash_index] = neuer_student;
}
Else explore the linked-list of hash_tabelle[hash_index] to store
the neuer_student at the end.
else
{
Student *tmp;
tmp = hash_tabelle[hash_index];
while (tmp->next_student!=NULL) {
tmp = tmp->next_student;
}
tmp->next_student = neuer_student;
}
Step 5 - to print the all items of the hash table (function print_hash_tabelle())
Reuse the same method to explore each linked-list pointer.
Warning: explore all item from 0 to MAX_HASH-1
void print_hash_tabelle()
{
for(int i = 0; i < MAX_HASH; i++){ // ERR != MAX_HASH - 1; i++){
printf("%d)\t", i);
Student *tmp = hash_tabelle[i];
while (tmp!=NULL) {
printf("%s (%d)", tmp->name, tmp->matnr);
tmp = tmp->next_student;
}
printf("\n");
}
}
Step 6 - free the memory of each item of the hash_tabelle[].
Free the allocated string free(tmp->name);.
Remove the current student hash_tabelle[i] = tmp->next_student;
Free the allocated student free(tmp);
Repeat until the end of the linked-list
That's all (no change in the main() except adding a call to hash_free() at the end).
void hash_free()
{
for(int i=0;i<MAX_HASH;i++) {
Student *tmp = hash_tabelle[i];
while (tmp!=NULL) {
free(tmp->name);
hash_tabelle[i] = tmp->next_student;
free(tmp);
tmp = hash_tabelle[i];
}
}
}
like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH 10
typedef struct student {
unsigned int matnr;
char *name;
struct student *next_student;
} Student;
Student *hash_tabelle[MAX_HASH];
void insert_student (unsigned int matnr, char *name){
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(strlen(name)+1);
strcpy(neuer_student->name, name);
neuer_student->matnr = matnr;
//neuer_student->next_student = NULL;
int hash_index = matnr % MAX_HASH;
Student head = { .next_student = hash_tabelle[hash_index] };
Student *prev = &head, *curr = head.next_student;
while(curr != NULL && curr->matnr <= neuer_student->matnr){
prev = curr;
curr = curr->next_student;
}
neuer_student->next_student = curr;
prev->next_student = neuer_student;
hash_tabelle[hash_index] = head.next_student;
}
void print_hash_tabelle(void){
for(int i = 0; i < MAX_HASH; i++){
printf("%d)\t", i);
for(Student *p = hash_tabelle[i]; p; p = p->next_student){
printf("%s (%d)\t", p->name, p->matnr);
}
printf("\n");
}
}
void free_hash_tabelle(void){
for(int i = 0; i < MAX_HASH; i++){
Student *p = hash_tabelle[i];
while(p){
Student *temp = p->next_student;
free(p->name);
free(p);
p = temp;
}
}
}
int main(void){
int matnr = -1;//for %d of scanf
char name[100];
while(1){
printf("Matrikelnummer(-1 for end input): ");fflush(stdout);
scanf("%d", &matnr);
if(matnr < 0)
break;
while(getchar() != '\n');
printf("Name: ");fflush(stdout);
fgets(name, sizeof name, stdin);
name[strcspn(name, "\n")] = 0;
insert_student(matnr, name);
}
print_hash_tabelle();
free_hash_tabelle();
return 0;
}

I m trying to sort the node by score. I do not know what error i am having

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
struct student{
char firstname[20];
char lastname[20];
double grade;
char zipcode[10];
struct student *next;
};
void display(struct student *first)
{
while (first != NULL)
{
printf("\nFirst name: %s", first->firstname);
printf("\tLast name: %s", first->lastname);
printf("\tGrade: %.2f", first->grade);
printf("\t ZipCode: %s", first->zipcode);
first = first->next;
}
}
/*void add_Record(struct student *first)
{
char r[20];
struct student *t;
t = first;
while (t != NULL)
{
if (t == NULL)
{
first = (struct student*)malloc(sizeof(struct student));
printf("\nEnter the first name of the student:");
scanf("%s", first->firstname);
printf("\nEnter the last name of the student:");
scanf("%s", first->lastname);
printf("\nEnter the score of the student:");
scanf("%lf", &first->grade);
printf("\nEnter the zipcode of the student:");
scanf("%s", first->zipcode);
}
}
}
void del()
{
struct student *back, *t, *k;
char r[10];
int flag = 0;
printf("\nEnter the last name of student you want to delete:");
scanf("%s", r);
if (strcmpi(r, first->lastname) == 0)
{
first = first->next;
flag = 1;
}
else
{
back = first;
k = first->next;
while (k != NULL)
{
if (strcmpi(r, k->lastname) == 0)
{
back->next = k->next;
flag = 1;
break;
}
}
}
if (flag == 0)
printf("\nThe element not found!!!");
}
*/
void search(struct student *first)
{
char r[10];
int flag = 0;
printf("\nEnter the zipcode you want to search:");
scanf("%s", r);
struct student *t;
t = first;
while (t != NULL)
{
if (strcmp(r, t->zipcode) == 0)
{
printf("\nFirst name: %s", t->firstname);
printf("\tLast name: %s", t->lastname);
printf("\tGrade: %.2f", t->grade);
printf("\t ZipCode: %s", t->zipcode);
flag = 1;
break;
}t = t->next;
}
if (flag == 0)
printf("\nThe zipcode not in database!!");
}
void sort(struct student *first)
{
struct student *temp;
temp = NULL;
while (first != NULL)
{
if (first-> grade > first->next->grade)
{
strcpy(temp->firstname, first->firstname);
strcpy(temp->lastname, first->lastname);
temp->grade = first->grade;
strcpy(temp->zipcode, first->zipcode);
strcpy(first->firstname, first->next->firstname);
strcpy(first->lastname, first->next->lastname);
first->grade = first->next->grade;
strcpy(first->zipcode, first->next->zipcode);
strcpy(first->next->firstname, temp->firstname);
strcpy(first->next->lastname, temp->lastname);
first->next->grade = temp->grade;
strcpy(first->next->zipcode, temp->zipcode);
break;
}
}
printf("\nThe sorted record by score are: \n");
display(first);
}
int main(void)
{
struct student *first = NULL, *last = NULL;
struct student *temp;
int n;
printf("\nEnter the number of student:");
scanf("%d", &n);
int i;
for (i = 0; i < n; i++)
{
temp = (struct student*)malloc(sizeof(struct student));
printf("\nEnter the first name of the student:");
scanf("%s", temp->firstname);
printf("\nEnter the last name of the student:");
scanf("%s", temp->lastname);
printf("\nEnter the grade of the student:");
scanf("%lf", &temp->grade);
printf("\nEnter the zipcode of the student:");
scanf("%s", temp->zipcode);
temp->next = first;
first = temp;
}
int o;
o = 1;
while (o != 0)
{
printf("\nMENU\n");
printf("\nEnter 1 for displaying database.");
printf("\nEnter 2 for inserting an record.");
printf("\nEnter 3 for deleting a record by lastname.");
printf("\nEnter 4 for searching a record by zipcode.");
printf("\nEnter 5 for sorting record by score.");
printf("\nEnter 0 for exit!");
printf("\nEnter the choice:");
scanf("%d", &o);
switch (o)
{
case 1:display(first); break;
/*case 2:insertafter(*first); break;
case 3:del(); break;*/
case 4:search(first); break;
case 5: sort(first); break;
case 0:exit(0); break;
default:printf("\nYou have entered a wrong choice!!!");
}
}
}
The problem is that how do i sort the scores by score. My code seems right but doesn't work. I made a temp structure and tried to swap values but it doesn't work. Am i doing the loop wrong? Or all my code is wrong?
Here are two answers to the problem
First one sorts the nodes in the node linked list by bubble sorting them, rearranging the linked list
Second one walks the linked list, copies a pointer to each one into an array and then sorts the array by using the struct grade members, the linked list remains unchanged
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define SWAP(T,x,y) {T *p = &(x); T *q = &(y); T z = *p; *p = *q; *q = z;}
struct student{
char firstname[20];
char lastname[20];
double grade;
char zipcode[10];
struct student *next;
};
struct student *head=NULL;
void add(char *f, char *s, double score) {
struct student *a;
a=(struct student*)malloc(sizeof(struct student));
strcpy(a->firstname,f);
strcpy(a->lastname,s);
a->grade = score;
a->next = head;
head = a;
}
void printout(char *label) {
struct student *node;
printf("%s\n",label);
for(node=head; node !=NULL; node=node->next) {
printf("%s %s %f\n", node->firstname, node->lastname, node->grade);
}
}
int main(int argc, char ** argv){
int mark=8;
struct student *walk, *prev;
add("Bob","Smith",10);
add("Eric","Von Däniken",90);
add("Morris","Minor",91);
add("Master","Bates",9);
add("Zoe","Bodkin",20);
add("Mary","Pippin",30);
/* bubble sort */
printout("before");
prev=head;
while(mark) {
mark=0;
for(walk=head;
walk != NULL;
walk=walk->next) {
if (walk->next && walk->grade > walk->next->grade) {
/* printf("swapping %s %s\n", walk->firstname, walk->next->firstname); */
mark=1;
if (walk == head) {
struct student *v2=walk->next;
struct student *v3=walk->next->next;
SWAP(struct student *, v3->next, v2->next);
SWAP(struct student *, head, v3->next);
walk = v3;
} else {
struct student *v1=prev;
struct student *v2=walk;
struct student *v3=walk->next;
SWAP(struct student *, v3->next, v2->next);
SWAP(struct student *, v1->next, v3->next);
walk = v3;
}
}
prev=walk;
}
}
printout("after");
return 0;
}
second version, uses qsort, retains linked list order
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
struct student{
char firstname[20];
char lastname[20];
double grade;
char zipcode[10];
struct student *next;
};
struct student *head=NULL;
size_t nodecount=0;
void add(char *f, char *s, double score) {
struct student *a;
a=(struct student*)malloc(sizeof(struct student));
strcpy(a->firstname,f);
strcpy(a->lastname,s);
a->grade = score;
a->next = head;
head = a;
nodecount++;
}
static int cmpgrade(const void *p1, const void *p2) {
struct student *g1, *g2;
g1=*(struct student **)p1;
g2=*(struct student **)p2;
return g1->grade > g2->grade;
}
int main(int argc, char ** argv){
int i;
struct student *walk,**sa, **sap;
add("Bob","Smith",10);
add("Eric","Von Däniken",90);
add("Morris","Minor",91);
add("Master","Bates",9);
add("Zoe","Bodkin",20);
add("Mary","Pippin",30);
/*copy into array of pointers*/
sa=calloc(sizeof (struct student*), nodecount);
sap=sa;
for(walk=head; walk != NULL; walk=walk->next) {
*sap = walk;
sap++;
}
printf("before\n");
for (i=0; i< nodecount; i++) {
printf("%s %s %f\n", sa[i]->firstname, sa[i]->lastname, sa[i]->grade);
}
/* qsort */
qsort(sa, nodecount, sizeof (struct student *), cmpgrade);
printf("after\n");
for (i=0; i< nodecount; i++) {
printf("%s %s %f\n", sa[i]->firstname, sa[i]->lastname, sa[i]->grade);
}
return 0;
}

hash table - linked lists - segmentation fault

I am trying to implement a hash table with linked list chaining. The following code below works -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TABSIZ 200
struct record {
struct record *next;
char name[BUFSIZ];
int data;
};
static struct record *htable[TABSIZ];
unsigned hash(char *s)
{
unsigned h;
for (h = 0; *s; s++)
h = *s;
//printf("%d", h%TABSIZ);
//I know its not a good hash function but i wanted to check chaining
return h % TABSIZ;
}
struct record *find(char *name)
{
struct record *item;
for (item = htable[hash(name)]; item; item = item->next)
{
if (strcmp(name, item->name) == 0)
return item;
}
return NULL;
}
struct record *insert(char *name,int value)
{
struct record *item;
unsigned h;
if ((item = find(name)) == NULL)
{
if ((item = malloc(sizeof (*item))) == NULL)
return NULL;
strcpy(item->name, name);
item->data=value;
h = hash(name);
item->next = htable[h];
htable[h] = item;
}
return item;
}
void printTable()
{
int i=0;
struct record *temp;
for(i=0;i<=TABSIZ;i++)
{
temp=htable[i];
while(temp!=NULL)
{
printf("\n%d - %s - %d\n", i,temp->name, temp->data);
temp=temp->next;
}
}
}
int main(void)
{
char buf[BUFSIZ];int value;
struct record *item;
do{
printf("Enter the name of the student:\n");
scanf("%s", buf);
if(strcmp(buf,"stop")==0) break;
printf("Enter the marks of the student:\n");
scanf("%d", &value);
if(insert(buf, value)==NULL)
{
break;
}
}while((strcmp(buf,"stop"))!=0);
printf("Enter a name to find: ");
scanf("%s", buf);
if((item=find(buf))!=NULL)
printf("The marks of the student is %d\n", item->data);
else printf("\n Not Found\n");
printTable();
return 0;
}
Now I am trying to remove the global variable and use local variable for the array of structures. I removed the global declaration of htable and declared it in main as
struct record *htable[TABSIZ];
and changed the functions to
struct record *find(struct record *htable, char *name);
struct record *insert(struct record *htable, char *name,int value);
and I'm calling the functions as
find(htable, name);
insert(htable,name,value);
but now my program is segfaulting. Am i passing the array of structures right? and have I declared it correctly. Any help would be greatly appreciated.
I was going down the wrong path with my earlier answer.
When it's a global, it's automatically initialized to 0.
When it's declared on the stack of main, it's not initialized.
Add a memset( htable, 0, sizeof(htable)) in main(), and that should return it to the previous behavior.
In printTable():
for(i=0;i<=TABSIZ;i++)
looks suspect. You prabably want:
void printTable()
{
unsigned int i;
struct record *temp;
for(i=0; i < TABSIZ;i++)
{
for (temp=htable[i]; temp!=NULL; temp=temp->next )
{
printf("\n%d - %s - %d\n", i,temp->name, temp->data);
}
}
}

Resources