Defining a structure in C with Malloc

I asked a question earlier about defining a structure using malloc. This was the answer I gave most:

struct retValue* st = malloc(sizeof(*st)); 

I showed my code to a friend, and we came to a stumbling block. Can someone explain why this code works? From my point of view, * st was not defined when you malloc it, so there can be any kind of garbage. It should be malloc(sizeof(struct retValue))

Thanks for any help

+7
c malloc memory structure
source share
4 answers

Sizeof looks at the type of the given expression; it does not evaluate the expression. Thus, you only need to make sure that the variables used in the expression are declared so that the compiler can infer their type.

In your example, st is already declared as pointer-to-struct-retValue. Therefore, the compiler can infer the type of the expression "* st".

Although it does not look like it is already declared in your code, the compiler has already taken care of this for you. All declarations in your code are moved to the beginning of the block in which they are executed by the compiler. Suppose you write

One way to illustrate the knowledge available to the compiler is to look at the intermediate output that it creates. Consider this code example ...

 struct retValue {long int a, long int b}; ... printf("Hello World!\n"); struct retValue* st = malloc(sizeof(*st)); 

Using gcc as an example and above, the code in main () of the test.c function looks at the intermediate output by running ...

 gcc -fdump-tree-cfg test.c 

The compiler will generate a test.c.022t.cfg file - Look at it and you will see

 [ ... removed internal stuff ...] ;; Function main (main) Merging blocks 2 and 3 main (argc, argv) { struct retValue * st; int D.3097; void * D.3096; # BLOCK 2 # PRED: ENTRY (fallthru) __builtin_puts (&"Hello World!"[0]); D.3096 = malloc (16); st = (struct retValue *) D.3096; D.3097 = 0; return D.3097; # SUCC: EXIT } 

Notice how the declaration was moved to the beginning of the block, and the argument in malloc has already been replaced with the actual value indicating the size of the type by which the expression was evaluated. As noted in the comments, the fact that the ad was moved to the top of the block is a detail of the compiler implementation. However, the fact that the compiler is able to do this, as well as insert the correct size in malloc, indicates that the compiler was able to output the necessary information from the input.

I personally prefer to specify the actual type name as the sizeof parameter, but this is probably a coding style issue where I would say that consistency is superior to personal preference.

+19
source share

The sizeof operator does not actually evaluate its operand - it just looks at its type. This is done at compile time, and not at run time. Therefore, it can be safely executed before a variable is assigned.

+19
source share

The declaration / definition of the type of structure is important, but not the definition of an object of such a class. When you reach malloc , the compiler will encounter a declaration / definition, otherwise you would fall into a compiler error.

The fact that sizeof doesn't evaluate its operands is a side issue.

Minus nit: remember that we need parentheses when we add type names to sizeof , like in:

 sizeof(struct retValue); 

and not in the case of objects, we just do:

 sizeof *st; 

See standard:

6.5.3 Unary operators Syntax

 unary-expression: [...] sizeof unary-expression sizeof ( type-name ) 
+1
source share

In C, sizeof is an operator and does not evaluate its argument. This can lead to “interesting” effects that someone who is not familiar with C. does not have to foresee. I mentioned this in more detail in my answer to the “Strangest Language” question.

0
source share

All Articles