How to check if structures are initialized or not

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 originally planned to set struct as null, but the compiler did not allow this. How to check if a structure is assigned or not?

Also, is it possible to recursively refer to the same structure within the structure?

+4
source share
5 answers

C is not null , it is null . So try the following:

 dict* NewDictionary(void) { return calloc(sizeof(dict)); } 

This fixes several issues:

  • You left value and key uninitialized so that they could store arbitrary garbage. Using calloc() will initialize everything to 0, which is null in the context of the pointer. It does not even take much more processing time.
  • You didn’t return anything. This behavior is undefined. If you finish without return , it is only thanks to good luck that something will be returned.
  • You used dict_pair instead of struct dict_pair . In C ++, struct names are in the namespace of a regular type, i.e. tx = { 0 }; is valid C ++, but in C you need to say struct tx = { 0 }; .
  • You did not check the return value of malloc() (now calloc() , but the same rules apply). If there is not enough memory, calloc() returns null . I would not want to play the null pointer during an accident. We do not need to check the return value here, because I am done with all the intermediate steps - calloc() is enough for us.

Note that calloc() little less portable. Although the standard requires that void *p = 0 point to a pointer to a null pointer, it does not require that the null pointer be "all bits set to zero", which technically does calloc() . If you do not want to use calloc() for this reason, here is a version that does the same 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?

Regarding your second question:

Also, is it possible to recursively refer to the same structure within the structure?

No, you cannot do this:

 struct t { struct tx; } 

But you can do it (this is what you do and what you want):

 struct t { struct t *x; } 

You may have a pointer to a struct inside the struct itself, but you cannot have an actual struct inside the struct itself. What you do is completely legal because you use pointers.

+8
source

You might want to consider calloc rather than malloc.

calloc fills the memory it allocates with 0s, so you will have the head and tail as NULL without an explicit assignment.

+1
source

I would use a statically assigned variable to initialize:

 dict* NewDictionary(void) { static dict null_dict; // no initializer, so zero by default dict *dictionary = malloc(sizeof *dictionary); *dictionary = null_dict; return dictionary; } 

This ensures that the element is correctly nullified, regardless of whether they are pointers, floating-point types, or integers.

+1
source

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 should be a pointer to a struct instead of directly defining a struct . If the latter were allowed, you would get an infinitely recursive definition of struct , which would be bad. See Chris Lutz's Answer for more details.

0
source

I use a trick that works for me.

 struct hello{ ....; ....; ....; }; struct hello *t; t=malloc(sizeof(struct hello)); free(t); t=NULL; 

Now you can easily check if t initialized or not. And there is no memory leak at all.

0
source

All Articles