2

I am trying to create a hash table in C from scratch. Here is a hash table with 1 byte (char*) keys and values I want to make, except I want my hash table to store keys and values as strings up to 32 characters long (char key[32], char value[32]). Here is my struct:

#define KV_SIZE 32

typedef struct hash_entry{
    char key[KV_SIZE];
    char value[KV_SIZE];
    struct hash_entry* next;
} hash_entry;

I am having trouble forming a function called create_entry() because I don't know how to assign my struct strings, key and value, to values.

// create an entry
hash_entry* create_entry(char key[KV_SIZE], char value[KV_SIZE]){
    printf("%s\n", key);
    hash_entry* entry = (hash_entry*)malloc(sizeof(hash_entry*));

    // I want entry->key and entry->value to store a string up to 32 chars long
    strncpy(entry->key, key, strlen(key)); // Error
    strncpy(entry->value, value, strlen(value)); // Error

    entry->next = NULL;

    return entry;
}

So far, it seems like I need my entry's to remain declared as pointers (hash_entry* entry) and not non-pointers (hash_entry entry) to be able to link them later.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
scrollout
  • 449
  • 4
  • 19
  • 2
    At least the size is wrong (size of a pointer). To avoid that error `entry = (hash_entry*)malloc(sizeof(hash_entry*));` ---> `entry = malloc(sizeof *entry);` (cast not needed, no usage of type) – chux - Reinstate Monica May 08 '20 at 22:51
  • @chux-ReinstateMonica getting rid of my casting of malloc() seemed to work... – scrollout May 08 '20 at 22:58
  • 1
    Wish I would have seen these comments before I posted my answer. My apologizes. If *all* you did was remove your cast, then there is another issue waiting to pop up later. Remove the cast and change the sizeof to the proper type inside of the malloc call –  May 08 '20 at 22:59
  • 2
    Using `strncpy` is seldom correct, and the way this code uses it is definitely wrong. You need to check that `strlen` returns a number less than 32. If it does, use `strcpy`. If it doesn't, then you need to handle the error. Either abort the program, or simply refuse to add the entry. – user3386109 May 08 '20 at 23:00
  • @BryanHeden I did that and my code ran, but the output had some extra random chars, so I also switched `strncpy` to `strcpy` and they went away. – scrollout May 08 '20 at 23:03
  • scrollout With 9 questions, you should know by now not to post an answer in the question. Post an answer below if desired. Question rolled-back. – chux - Reinstate Monica May 09 '20 at 01:08

2 Answers2

0
hash_entry* entry = (hash_entry*)malloc(sizeof(hash_entry));
0

Here's what fixed my code:

hash_entry* create_entry(char key[HASH_SIZE], char value[HASH_SIZE]){
    // No casting needed and don't use sizeof(pointer)
    // use sizeof(hash_entry) to get the full size of your struct
    hash_entry* entry = malloc(sizeof(hash_entry));

    // aside: don't forget to check the size of your strings
    if(strlen(key) < KV_SIZE && strlen(value) < KV_SIZE){
        // use strcpy instead of strncpy
        strcpy(entry->key, key);
        strcpy(entry->value, value);
        entry->next = NULL;

        return entry;
    }
    return NULL;
}
scrollout
  • 449
  • 4
  • 19