C doesn't have null
, it has NULL
. So try this:
dict* NewDictionary(void) {
return calloc(sizeof(dict));
}
This fixes a few problems:
- You were leaving
value
and key
uninitialized, so they could hold random garbage. Using calloc()
will initialize everything to 0, which in pointer context is NULL
. It won't even take that much more processing time.
- You weren't returning anything. This is undefined behavior. If you function ends without a
return
statement, it's only by sheer luck that anything will be returned.
- You were using
dict_pair
instead of struct dict_pair
. In C++, struct
names are in the regular type namespace, i.e. t x = { 0 };
is valid C++, but in C you'd need to say struct t x = { 0 };
.
- You weren't checking the return value of
malloc()
(now calloc()
but same rules apply). If there isn't enough memory, calloc()
returns NULL
. I'd hate to dereference a NULL
pointer on accident. We don't have to check the return value here because I've done away with all the intermediate steps - calloc()
is enough for us.
Note that calloc()
is slightly less portable. Even though the standard does require that void *p = 0
sets the pointer to a null pointer, it doesn't require that the null pointer be "all bits set to zero", which is what calloc()
technically does. If you don't want to use calloc()
for this reason, here's a version that does the same thing with malloc()
:
dict* NewDictionary(void) {
dict *dictionary = malloc(sizeof(dict));
if(dictionary) {
dictionary->head = NULL;
dictionary->tail = NULL;
dictionary->value = NULL;
dictionary->key = NULL;
}
return dictionary;
}
Or:
dict* NewDictionary(void) {
dict *dictionary = malloc(sizeof(dict));
if(dictionary == NULL) return NULL;
dictionary->head = NULL;
dictionary->tail = NULL;
dictionary->value = NULL;
dictionary->key = NULL;
return dictionary;
}
See how much nicer the calloc()
version is?
As to your second question:
Also, can I refer recursively declare the same struct inside the struct?
No, you can't do this:
struct t {
struct t x;
}
But you can do this (which is what you're doing, and what you want):
struct t {
struct t *x;
}
You can have a pointer to a struct
inside the struct
itself, but you can't have the actual struct
inside the struct
itself. What you're doing is perfectly legal, because you're using pointers.