pete said:
(e-mail address removed) wrote:
[... brutal context snippage for didactic purposes ...]
what is the trade off between the following two allocations
1) p = malloc( sizeof(sn) );
2) p = malloc( sizeof(*p) );
Using only the context available in this reply -- that
is, looking only at the two lines of code in the question
and not referring back to the declaration of `p' in your
question -- which line is easier to check for correctness?
Q.E.D.
Generally in programs involving linked lists i have seen the latter
one being used most often.
now p is simply a pointer variable, if by
accident if p points to NULL , p = malloc( sizeof(*p) ); will not
give correct allocation isn't it....??????
sizeof doesn't evaluate its operand.
(sizeof *p) is a compile time constant,
p doesn't even have to be initialized.
If p points to type int,
then you have all the information that you need,
in order to determine that (sizeof *p) equals (sizeof(int)).
The value of p doesn't matter in that case.
... and the reason malloc(sizeof *p) is preferred is that
you don't need to worry that you might accidentally write the
wrong type. You don't need to go back to the declaration of
p to discover what type to write, nor to check that the size
you wrote is the proper one.
Mismatches can be particularly insidious and hard to
catch. You'll see something like
int32_t *ptr;
/* 193 lines later: */
ptr = malloc(N * sizeof(int));
.... and it may work just fine on the platform where you wrote
and tested the code, where int32_t and int happen to have the
same size. But then you move the code to another platform
where int is only 16 bits wide, and suddenly the allocation
is no longer big enough and you start getting mysterious bugs.
A particularly dangerous form occurs when there are many
related types with similar names:
typedef struct { ... } MessageHeader;
typedef struct { ... } MessagePayload;
typedef struct { ... } MessageSummary;
...
MessageHeader *hdr;
MessagePayload *pay;
MessageSummary *sum;
...
hdr = malloc(sizeof(MessageHeader));
pay = malloc(sizeof(MessageHeader));
sum = malloc(sizeof(MessageSummary));
.... and as before, with the quirks of structure padding and
so on, it might actually work for a quite a while before
the error is discovered.
Using the `ptr = malloc(count * sizeof *ptr)' form (the
multiplication can be omitted if the count is known to be 1)
avoids such pitfalls. It doesn't guarantee that there are
no errors -- maybe `count' should have been `(count + 1)'
or some such -- but at least you're allocating "things" of
the proper size.