Reputation: 11268
I have been trying to implement hash-tables using uthash.h, following the (excellent) documentation I have been able to get the add and find functions to work with the following code:
#include <stdio.h>
#include "../src/uthash.h"
struct my_struct
{
int id; /* key */
char name[10];
double height;
UT_hash_handle hh; /* makes this structure hashable */
};
/* hash-table declared as a global variable */
struct my_struct *users = NULL; /* important! initialize to NULL */
void add_user(int user_id, char *name, double height) {
struct my_struct *s;
s = malloc(sizeof(struct my_struct));
s->id = user_id;
strcpy(s->name, name);
s->height = height;
HASH_ADD_INT( users, id, s ); /* id: name of key field */
}
struct my_struct *find_user(int user_id) {
struct my_struct *s;
HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */
return s;
}
int main()
{
add_user(users, 1, "ben", 1.85);
struct my_struct *user;
user = find_user(users, 1);
printf("user id: %d user name: %s height: %g\n", user->id, user->name, user->height);
return 0;
}
this was a good start, but I was unhappy with having the head of the hash declared as a global variable and would like to pass it in to the add and find functions as a parameter, e.g.:
#include <stdio.h>
#include "../src/uthash.h"
struct my_struct
{
int id; /* key */
char name[10];
double height;
UT_hash_handle hh; /* makes this structure hashable */
};
void add_user(struct my_struct *users, int user_id, char *name, double height) {
struct my_struct *s;
s = malloc(sizeof(struct my_struct));
s->id = user_id;
strcpy(s->name, name);
s->height = height;
HASH_ADD_INT( users, id, s ); /* id: name of key field */
}
struct my_struct *find_user(struct my_struct *users, int user_id) {
struct my_struct *s;
HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */
return s;
}
int main()
{
/* hash_table declared as a local variable and passed in as a parameter to
* add_user and find_user functions */
struct my_struct *users = NULL; /* important! initialize to NULL */
add_user(users, 1, "ben", 1.85);
struct my_struct *user;
user = find_user(users, 1);
printf("user id: %d user name: %s height: %g\n", user->id, user->name, user->height);
return 0;
}
this version is causing a SEG fault on the printf, it looks like nothing has been added to the hash table. can't really see where the second version is going wrong. surely it can't be a requirement to declare all your hash-tables as global variables to get it to work?
probably missed something obvious - but I can't see what it is...
Upvotes: 1
Views: 1108
Reputation: 3089
If you want to modify a pointer inside a function, you must use its address So, function
add_user(struct my_struct *users, int user_id, char *name, double height)
must be
add_user(struct my_struct **users, int user_id, char *name, double height)
if not, pointer is not modified.
of, course, inside add_user
use
HASH_ADD_INT( *users, id, s )
Upvotes: 4