Reputation: 17284
typedef struct dict_pair {
void *key;
void *value;
struct dict_pair *head;
struct dict_pair *tail;
} dict;
dict* NewDictionary(void) {
dict *dictionary = malloc(sizeof(dict_pair));
dictionary->head = null;
dictionary->tail = null;
}
int main(void) {
dict *dictionary = NewDictionary();
}
I had initially planned to set the structs as null but the compiler does not allow it. How can I check if a struct is assigned or not?
Also, can I refer recursively declare the same struct inside the struct?
Upvotes: 4
Views: 12616
Reputation: 3543
I'm using a trick which is working for me.
struct hello{
....;
....;
....;
};
struct hello *t;
t=malloc(sizeof(struct hello));
free(t);
t=NULL;
Now u can easily check if t
is initialized or not. And there is no memory leak at all.
Upvotes: 0
Reputation: 169563
I'd use a statically allocated variable for initialization:
dict* NewDictionary(void) {
static dict null_dict; // no initializer, so zero by default
dict *dictionary = malloc(sizeof *dictionary);
*dictionary = null_dict;
return dictionary;
}
This guarantees that member are correctly zeroed, regardless whether they're pointers, floating point or integer types.
Upvotes: 1
Reputation: 4254
You can set them as NULL
, but not as null
. C is case-sensitive, and the NULL
constant is all caps.
And to answer your second question, yes, struct
definitions can be recursive in a sense. The internal reference has to be a pointer to the struct
, instead of a straight definition of the struct
. If the latter was allowed, you would end up with an infinitely recursing struct
definition, which would be a bad thing. See Chris Lutz's answer for more details.
Upvotes: 0
Reputation: 75389
C doesn't have null
, it has NULL
. So try this:
dict* NewDictionary(void) {
return calloc(sizeof(dict));
}
This fixes a few problems:
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.return
statement, it's only by sheer luck that anything will be returned.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 };
.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.
Upvotes: 8
Reputation:
You may want to consider calloc rather than malloc.
calloc fills the memory it allocates with 0s, so you'll have your head and tail as NULL w/o explicit assignment.
Upvotes: 1