In a recent post, I realised that when allocating a structure variable, passing the dereferenced pointer deemed a better practice in contrast to passing the structure type to sizeof()
. This is basically because the former is more resilient to code changes than the latter.
Which suggests, that in the following code method 1 is deemed a better practice than method 2.
typedef struct X_ {
int x;
int y;
int z;
} X;
int main() {
X* obj1 = malloc(sizeof(*obj1)); // ----> method 1
X* obj2 = malloc(sizeof(X)); // ----> method 2
return 0;
}
The question is, how valid is it to dereference obj1
in method 1 ? Inside malloc
, obj1
is still unconstructed/uninitialized memory which suggests that dereferencing of obj1
happening inside sizeof()
shouldn't be valid.
Let me make a guess what makes method 1 valid. Is this because since sizeof()
is a compile time operation dereferencing obj1
gets translated into method 2 by the compiler?
Could someone please elaborate the technical validity of this by referring to the relevant C standards?
The sizeof expression where the operand is not a variable length array is a non evaluated expression. So this expression
sizeof(*obj1)
is well-formed.
From the C Standard (6.5.3.4 The sizeof and alignof operators)
2 The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant
As for your question relative to the best method of specifying an argument of malloc
X* obj1 = malloc(sizeof(*obj1)); // ----> method 1
X* obj2 = malloc(sizeof(X)); // ----> method 2
then if the type X
is visible in the point of using malloc like in this case
X* obj1 = malloc(sizeof(*obj1)); // ----> method 1
then this approach is preferable.
However if the type is not visible like for example
obj1 = malloc(sizeof(*obj1)); // ----> method 1
then I prefer explicitly to specify the type like
obj1 = malloc(sizeof( X ));
Otherwise for example this code snippet
p = malloc( *p );
q = malloc( *q );
does not give enough information for the reader of the code. And the reader will need to scroll the source code forward and backward to find the declarations of p
and q
to determine their types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With