My professor told me that the following code is incorrect:
int *array = malloc(sizeof *array * length);
And that it should instead be:
int *array = malloc(length * sizeof(int));
He said that you're supposed to encase the type between brackets for sizeof
, and that length must come before the sizeof
operator. He said that I can use *array
instead of int
, but that he preferred the latter.
My biggest question is why is it that length must come before size when calling malloc
, but also why it's preferrable to use the pointer type instead of the pointer itself with sizeof
.
He also mentioned that casting (i.e. (int*)
) is desirable, but I'm not sure why it is necessary.
CodePudding user response:
Both are valid, but many veteran programmers will prefer the way you did it.
The advantage of using sizeof *array
as opposed to sizeof(int)
is that if you happen to change the type of array
then you don't need to change how you do the allocation.
There's also no technical reason to multiply by length
first instead of the element size. If anything, when looking at a call to malloc
the first thing you want to know is how many "things" you're allocating, so from a readability standpoint putting the length first might make more sense. On the other hand, because the result of the sizeof
operator is unsigned, putting it first guarantees that the math is done with unsigned types if you have multiple array dimensions.
You also don't want to cast the return value of malloc
as that can mask other errors in your code, specifically a missing #include <stdlib.h>
CodePudding user response:
The sizeof operator is defined the following way
sizeof unary-expression
So this line
int *array = malloc(sizeof *array * length);
is equivalent to
int *array = malloc( ( sizeof *array ) * length);
But the original line though it is correct is less clear. So the preferable way to write this line is
int *array = malloc( length * sizeof *array );
or even better
int *array = malloc( length * sizeof( *array ) );
You may write also like
int *array = malloc(length * sizeof(int));
but if the type of the elements of the dynamically allocated array will be changed then you need to make changes in two places like for example
long *array = malloc(length * sizeof(long));
^^^^ ^^^^
If you will forget to change the type in the sizeof expression then there can be a bug that will be difficult to find in a big project.
In this line
int *array = malloc( length * sizeof( *array ) );
you need make a change only in one place
long *array = malloc( length * sizeof( *array ) );
^^^^
So this declaration is less error prone.
CodePudding user response:
The only problem with the first one is this (I changed from 'array' to a name that doesnt carry such obvious connotations)
int *twoodle = malloc(sizeof *twoodle * length);
int *twoodle = malloc(sizeof *twoodle);
Both are valid, will compile, but only one is correct. And its impossible to tell just by looking at it
I know that the other format has the same problem but people think (it was stated above ) "So this declaration is less error prone.". But you can still make errors here too
Point is , make sure your mallocs are correct (duh)