General problem: implementing a dictionary.
Specific problem: according to gdb, my allocations and everything are working exactly as intended. The problem arises once types_dict_add is called with a key of "c". Everything is once again allocated as it should be and the entire dictionary is intact throughout the function context (all pointers are accessible and the structures at those pointers have their set values), but once the function exits back to main, the mydict
pointers are all out of bounds. The actual pointer addresses stored in the mydict
are all unchanged, but are suddenly inaccessible. Up until the call with "c", the mydict
is also intact and as it should be in main.c
What am I doing wrong here? It's really confusing me as I've checked with gdb over and over again and the len
value is being set correctly so there is definitely a proper amount of space being realloc
'd each go.
types.h
#ifndef _TYPES_H_
#define _TYPES_H_
union types {
long int ival;
char *sval;
};
struct kv {
char* key;
union types val;
};
struct kv **types_dict_init();
void types_dict_add(struct kv**, char*, union types);
struct kv *types_dict_get(char*);
void types_dict_free(struct kv**);
#endif
types.c
struct kv **
types_dict_init()
{
struct kv **newdict;
newdict = calloc(1, sizeof(struct kv*));
newdict[0] = NULL;
return (newdict);
}
void
types_dict_add(struct kv** d, char* k, union types v)
{
int len;
if (d[0] == NULL) {
d = realloc(d, sizeof(struct kv*) * 2);
d[0] = malloc(sizeof(struct kv));
d[0]->key = k;
d[0]->val = v;
d[1] = NULL;
} else {
for (len = 1; d[len - 1] != NULL; len++)
;
d = realloc(d, sizeof(struct kv*) * ++len);
d[len - 2] = malloc(sizeof(struct kv));
d[len - 2]->key = k;
d[len - 2]->val = v;
d[len - 1] = NULL;
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "bencode/types.h"
int main(int argc, char **argv)
{
struct kv **mydict;
union types toadd;
toadd.sval = "test";
mydict = types_dict_init();
types_dict_add(mydict, "a", toadd);
types_dict_add(mydict, "b", toadd);
types_dict_add(mydict, "c", toadd);
types_dict_add(mydict, "d", toadd);
for(int i = 0; i < 4; i++)
printf("%d: %s\n", i, mydict[i]->key);
return (EXIT_SUCCESS);
}