简体   繁体   中英

C hash-table seg fault issue

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, eg:

#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...

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 )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM