Unfortunately problem looks for me to be quite complex.
I'm having set of structs and function. Pardon me for terrible naming.
hashmap.h
#ifndef HASHMAP_H
#define HASHMAP_H
typedef struct HashMapNode HashMapNode;
struct HashMapNode {
char *key;
int value;
HashMapNode *collision;
};
typedef struct {
int size;
HashMapNode **map;
} HashMap;
HashMap *hashmap_new(size_t size);
HashMapNode *hashmap_node_new(HashMapNode *node);
#endif
hashmap.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "hashmap.h"
HashMapNode *hashmap_node_new(HashMapNode *node){
node = malloc(sizeof(HashMapNode));
node->key = NULL;
node->value = 0;
node->collision = NULL;
return node;
};
HashMap *hashmap_new(size_t size){
HashMap *hash_map = malloc(sizeof(HashMap));
hash_map->size = size;
hash_map->map = malloc(sizeof(HashMapNode*) * size);
HashMapNode *node;
for (int i = 0; i < hash_map->size; i++){
node = hashmap_node_new(hash_map->map[i]);
printf("Node pointer: %p, key pointer: %p, collision pointer %p\n", node, node->key, node->collision);
};
return hash_map;
};
Here is program workflow and error.
main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "hashmap.h"
int main(){
HashMap *hash_map = hashmap_new(100);
printf("%p\n", hash_map->map[4]->key);
return 0;
};
Output:
...
Node pointer: 0x5607cb89b8b0, key pointer: (nil), collision pointer (nil)
Node pointer: 0x5607cb89b8d0, key pointer: (nil), collision pointer (nil)
Node pointer: 0x5607cb89b8f0, key pointer: (nil), collision pointer (nil)
Node pointer: 0x5607cb89b910, key pointer: (nil), collision pointer (nil)
Node pointer: 0x5607cb89b930, key pointer: (nil), collision pointer (nil)
Node pointer: 0x5607cb89b950, key pointer: (nil), collision pointer (nil)
Node pointer: 0x5607cb89b970, key pointer: (nil), collision pointer (nil)
Segmentation fault (core dumped)
Program fails at:
(Important fact is that it fails to print pointer for index > 3)
Program received signal SIGSEGV, Segmentation fault.
main () at usage.c:18
18 printf("%p\n", hash_map->map[4]->key);
GDB debug:
(gdb) print hash_map
$11 = (HashMap *) 0x5555555594a0
(gdb) print hash_map->map[0]->key
$12 = 0x7ffff7fa82f0 <main_arena+1648> "\340\202\372\367\377\177"
(gdb) print hash_map->map[1]->key
$13 = 0x7ffff7fa82f0 <main_arena+1648> "\340\202\372\367\377\177"
(gdb) print hash_map->map[2]->key
$14 = 0x0
(gdb) print hash_map->map[3]->key
$15 = 0x0
(gdb) print hash_map->map[4]->key
Cannot access memory at address 0x61590a616963616d
Not really sure where am I making a mistake..
The function hashmap_node_new
creates a new node and returns it, but it doesn't modify the original pointer that was passed in to the function by its argument.
That means that the statement
node = hashmap_node_new(hash_map->map[i]):
will not modify hash_map->map[i]
. You need to assign the pointer the function returns back to hash_map->map[i]
:
node = hashmap_node_new(hash_map->map[i]):
hash_map->map[i] = node;
The reason that the hashmap_node_new
doesn't modify the original pointer you pass in as the argument is because arguments in C are passed by value. That means the original value is copied, and the function only works on the copy not the original.
This is basically the same as something like:
int set_int(int value)
{
value = 5;
return value;
}
// ...
int my_value;
int new_value;
new_value = set_int(my_value);
And expecting my_value
to become initialized.