Given
struct node
{
int a;
struct node * next;
};
To malloc a new structure,
struct node *p = malloc(sizeof(*p));
is safer than
struct node *p = malloc(sizeof(struct node));
Why? I thought they are the same.
Given
struct node
{
int a;
struct node * next;
};
To malloc a new structure,
struct node *p = malloc(sizeof(*p));
is safer than
struct node *p = malloc(sizeof(struct node));
Why? I thought they are the same.
It is convenient, because you can convert this:
Into this:
Or, for an array:
And why is this safe? Because the user who uses these macros would be less likely to make mistakes which were outlined by AndreyT, just as in the case of
DIM()
to get the size of a static array.This is also safer, because the user does not need to make the static array size consistent in several places. Set the array size in one place and then just use the
DIM()
and you're done! The compiler takes care of it for you.Because if at some later point in time
p
is made to point to another structure type then your memory allocation statement usingmalloc
doesn't have to change, it still allocates enough memory required for the new type. It ensures:In general it is always a good practice to not rely on concrete types and the the first form just does that ,it doesn't hard code a type.
It is safer becuse you don't have to mention the type name twice and don't have to build the proper spelling for "dereferenced" version of the type. For example, you don't have to "count the stars" in
Compare that to the type-based
sizeof
inwhere you have too make sure you used the right number of
*
undersizeof
.In order to switch to another type you only have to change one place (the declaration of
p
) instead of two. And people who have the habit of casting the result ofmalloc
have to change three places.More generally, it makes a lot of sense to stick to the following guideline: type names belong in declarations and nowhere else. The actual statements should be type-independent. They should avoid mentioning any type names or using any other type-specific features as much as possible.
The latter means: Avoid unnecessary casts. Avoid unnecessary type-specific constant syntax (like
0.0
or0L
where a plain0
would suffice). Avoid mentioning type names undersizeof
. And so on.It does not affect safety directly, but one can claim it may prevent a bug in future revisions. On the other hand it is easy to forget that little
*
. How about making it a type, it is certainly cleaner.Then you can do this: