DavidLeeds / hashmap

Templated type-safe hashmap implementation in C using open addressing and linear probing for collision resolution.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

global hashmap can't be seen outside of where it's declared

lpipes opened this issue · comments

Hi, I'm trying to use this hashmap as a global variable but I can't figure out how the variable can be seen outside of the scope of where it's declared. I've loaded the hashmap correctly:
(gdb) p map $499 = {map_base = {table_size_init = 128, table_size = 2048, size = 1466, table = 0x555558c909b0, hash = 0x55555556a12f <hashmap_hash_string>, compare = 0x7ffff70a9c50, key_dup = 0x0, key_free = 0x0}, map_types = 0x7fffffffb550}

But when I enter into a function, the map has a different address and is empty:
(gdb) p map $501 = (struct hashmap_base *) 0x0

The struct also seems to be different and the two maps have different addresses. I've used the macro HASHMAP in the main function because I couldn't get the program to compile using a typedef in the header file. Any ideas on how I can get this to work?

Hi @lpipes,

Can you provide a snippet of code with your desired usage? I might be able to identify an issue. There should be no problems using this library how you have described.

As always, I would highly recommend compiling C code with -Wall and -Werror compiler options so the compiler identifies obvious issues.

Thank you! It's probably something I don't understand. I tried to make this MWE but now it won't compile. I tried to compile with gcc -g -pg -w -o main main.c findABC.c hashmap.c

global.h:

#include "hashmap.h"
#include "hashmap_base.h"

typedef struct leafMap{
	char* name;
	int root;
	int node;
}leafMap;
extern struct hashmap_base map;

main.c:

#include <stdbool.h>
#include <stdint.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "hashmap.h"
#include "hashmap_base.h"
#include "global.h"

struct hashmap_base map;

int main()
{
        HASHMAP(char, struct leafMap) map;
	hashmap_init(&map,hashmap_hash_string, strcmp);
	struct leafMap *l;
	l = malloc(sizeof(leafMap));
	l->name=malloc(10*sizeof(char));
	strcpy(l->name,"ABC");
	l->root=12;
	l->node=5;
	hashmap_put(&map,l->name,l);
	findABC();
	free(l->name);
	free(l);
}

and findABC.c:

#include <stdbool.h>
#include <stdint.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "hashmap.h"
#include "hashmap_base.h"
#include "global.h"

void findABC(){
	struct leafMap *l;
	l=hashmap_get(&map,"ABC");
	printf("Key: %s, Root: %d, Node: %d\n", l->name, l->root, l->node);
}

I'm able to compile and run this code correctly but not the previous code. I compiled with gcc -g -pg -w -o main main.c hashmap.c

global.h:

#include "hashmap.h"
#include "hashmap_base.h"

typedef struct leafMap{
	char* name;
	int root;
	int node;
}leafMap;

main.c:

#include <stdbool.h>
#include <stdint.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "hashmap.h"
#include "hashmap_base.h"
#include "global.h"

HASHMAP(char, struct leafMap) map;

void findABC(){
	struct leafMap *l;
	l=hashmap_get(&map,"ABC");
	printf("Key: %s, Root: %d, Node: %d\n", l->name, l->root, l->node);
}
int main()
{
        hashmap_init(&map,hashmap_hash_string, strcmp);
	struct leafMap *l;
	l = malloc(sizeof(leafMap));
	l->name=malloc(10*sizeof(char));
	strcpy(l->name,"ABC");
	l->root=12;
	l->node=5;
	hashmap_put(&map,l->name,l);
	findABC();
	free(l->name);
	free(l);
}
./main 
Key: ABC, Root: 12, Node: 5

Your application scenario is the same as mine. I use global variables and use locking. I also have similar problems. I once suspected that it was my own use problem.

I use this to replace the redundant map table of C++. Now hashmap supports adding, deleting, and querying, but it has not been modified.

A few notes:

  1. In the original code, the FindABC() declaration was not visible to main.c. The second (working) version moved the function to main.c where it was visible.
  2. There is no need to include hashmap_base.h. Just include hashmap.h.
  3. Don't forget to call hashmap_cleanup() to free memory used by the data structure when you're done using it.