Skip to content

Instantly share code, notes, and snippets.

@kylef
Created March 27, 2009 17:11
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save kylef/86784 to your computer and use it in GitHub Desktop.
Save kylef/86784 to your computer and use it in GitHub Desktop.
A key/value dictionary system in C
/* A key/value dict system in C */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TEST TRUE /* Comment this line out to compile without a main function (used when including into another application). */
typedef struct dict_t_struct {
char *key;
void *value;
struct dict_t_struct *next;
} dict_t;
dict_t **dict_alloc(void) {
return malloc(sizeof(dict_t));
}
void dict_dealloc(dict_t *dict) {
dict_t *ptr;
for (ptr = dict; ptr != NULL; ptr = ptr->next) {
free(ptr);
}
}
void *dict_getItem(dict_t *dict, char *key) {
dict_t *ptr;
for (ptr = dict; ptr != NULL; ptr = ptr->next) {
if (strcmp(ptr->key, key) == 0) {
return ptr->value;
}
}
return NULL;
}
void dict_delItem(dict_t **dict, char *key) {
dict_t *ptr, *prev;
for (ptr = *dict, prev = NULL; ptr != NULL; prev = ptr, ptr = ptr->next) {
if (strcmp(ptr->key, key) == 0) {
if (ptr->next != NULL) {
if (prev == NULL) {
*dict = ptr->next;
} else {
prev->next = ptr->next;
}
} else if (prev != NULL) {
prev->next = NULL;
} else {
*dict = NULL;
}
free(ptr->key);
free(ptr);
return;
}
}
}
void dict_addItem(dict_t **dict, char *key, void *value) {
dict_delItem(dict, key); /* If we already have a item with this key, delete it. */
dict_t *d = malloc(sizeof(struct dict_t_struct));
d->key = malloc(strlen(key)+1);
strcpy(d->key, key);
d->value = value;
d->next = *dict;
*dict = d;
}
int dict_size(dict_t *dict) {
int size = 0;
dict_t *ptr;
for (ptr = dict; ptr != NULL; ptr = ptr->next) {
size++;
}
return size;
}
dict_t **dict_invert(dict_t *dict) {
dict_t **invert = dict_alloc();
dict_t *ptr;
for (ptr = dict; ptr != NULL; ptr = ptr->next) {
dict_addItem(invert, ptr->value, ptr->key);
}
return invert;
}
#ifdef TEST
int main(int argc, char **argv) {
/* Create a dict */
dict_t **dict = dict_alloc();
/* lets add foo, and bar to the dict */
dict_addItem(dict, "foo", "bar");
dict_addItem(dict, "bar", "foo");
/* and print their values */
printf("%s %s (size: %i)\n", (char *)dict_getItem(*dict, "foo"), (char *)dict_getItem(*dict, "bar"), dict_size(*dict));
/* lets delete them */
dict_delItem(dict, "foo");
dict_delItem(dict, "bar");
/* see, their gone, there NULL */
printf("%s %s (size: %i)\n", (char *)dict_getItem(*dict, "foo"), (char *)dict_getItem(*dict, "bar"), dict_size(*dict));
/* add them again to proof it works */
dict_addItem(dict, "foo", "bar");
dict_addItem(dict, "bar", "foo");
dict_addItem(dict, "bar", "pan");
/* see, here */
printf("%s %s (size: %i)\n", (char *)dict_getItem(*dict, "foo"), (char *)dict_getItem(*dict, "bar"), dict_size(*dict));
/* invert the dict */
dict_t **invert = dict_invert(*dict);
printf("%s %s (size: %i)\n", (char *)dict_getItem(*invert, "bar"), (char *)dict_getItem(*invert, "pan"), dict_size(*invert));
dict_dealloc(*invert);
dict_delItem(dict, "foo");
dict_delItem(dict, "bar");
dict_dealloc(*dict);
return 0;
}
#endif
@tomaszkyc
Copy link

Hi,

I've noticed a two bugs in this little struct. Want to make a merge request but how can I do this?

@rosjat
Copy link

rosjat commented May 5, 2020

Hi,

I've noticed a two bugs in this little struct. Want to make a merge request but how can I do this?

you can't , simply make a comment with your changes and hope the author will update it.

@aiixu
Copy link

aiixu commented Dec 14, 2020

Hello, i tried to use your functions but each time i get the error "Exception thrown: read access violation. ptr was 0xFFFFFFFFFFFFFFFF." in delItem (same thing if i just copy paste the whole code and compile it). Any idea ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment