malloc

A

aarklon

Hi all,

suppose i am having a structure as follows

typedef struct node
{
int n;
struct node * next;
}sn;

sn *p;

now which of the following is the correct way to allocate memory and
why ?

OR

what is the trade off between the following two allocations

1) p = malloc( sizeof(sn) );
2) p = malloc( sizeof(*p) );
 
E

Eric Sosman

[... 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.
 
A

aarklon

[... 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....??????
 
P

pete

[... 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.
 
E

Eric Sosman

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.
 
D

David T. Ashley

Hi all,

suppose i am having a structure as follows

typedef struct node
{
int n;
struct node * next;
}sn;

sn *p;

now which of the following is the correct way to allocate memory and
why ?

OR

what is the trade off between the following two allocations

1) p = malloc( sizeof(sn) );
2) p = malloc( sizeof(*p) );

The compiler treats each of these two identically, and will simply call
malloc with a constant (the same constant in either case).

The first form is 33% better than the first. The reason is that in the
second form, you normally have to use the SHIFT key on your keyboard, for 3
keystrokes. For the first form, only two keystrokes. If you had to type
the malloc() statement several million times, the second form may put more
wear on your keyboard and fingers.
 
C

CBFalconer

David T. Ashley said:
The compiler treats each of these two identically, and will simply
call malloc with a constant (the same constant in either case).
True.


The first form is 33% better than the first. The reason is that
in the second form, you normally have to use the SHIFT key on your
keyboard, for 3 keystrokes. For the first form, only two
keystrokes. If you had to type the malloc() statement several
million times, the second form may put more wear on your keyboard
and fingers.

Utter nonsense. See some of the other answers, including Sosman.
 
D

David T. Ashley

CBFalconer said:
Utter nonsense. See some of the other answers, including Sosman.

I actually would improve on the second form somewhat.

#define M(ptr) ptr=malloc(sizeof(*ptr));

M(ptr)

That brings the whole affair down to 6 keystrokes if one does it
repetitively -- quite an improvement.

---------

All kidding and bad humor aside ...

The superior form is the one that minimizes the probability of human error.
The second form is superior because it localizes the search to one line of
code.
 
M

MisterE

what is the trade off between the following two allocations

1) p = malloc( sizeof(sn) );
2) p = malloc( sizeof(*p) );

I have seldom seen people use *p. Normally you use only the type definition
itself and try not to use a variable at all. I think this is because some
early compilers would only allow type definitions. All the 'guidelines' at
companies I have coded for always ask to use type definitions only, never
variables.
 
I

Ian Collins

MisterE said:
I have seldom seen people use *p. Normally you use only the type definition
itself and try not to use a variable at all. I think this is because some
early compilers would only allow type definitions. All the 'guidelines' at
companies I have coded for always ask to use type definitions only, never
variables.
Yet more nonsense, verging on bollocks. Where is the variable in
sizeof(*p)?
 
B

Bartc

CBFalconer said:
Utter nonsense. See some of the other answers, including Sosman.

He has a point. I once did so much typing that my fingers hurt and I had to
type wearing woollen gloves.

But, if that is really a problem then C is full of punctuation! In that case
use a different language -- or a softer keyboard.
 
M

Mark Bluemel

I have CBF killfiled but had to reply to this, simply to say "ROTFL"...

Did anyone else hear a "Whoosh" as DTA's post past right over Chuck's
head?
 
J

Joachim Schmitz

David T. Ashley said:
I actually would improve on the second form somewhat.

#define M(ptr) ptr=malloc(sizeof(*ptr));

M(ptr)

That brings the whole affair down to 6 keystrokes if one does it
repetitively -- quite an improvement.
Further improvement:
#define M(p) p=malloc(sizeof(*p));

Saves 6 keystrokes first time and additional 2 on every repitition :cool:

Bye, Jojo
 
V

vippstar

He has a point. I once did so much typing that my fingers hurt and I had to
type wearing woollen gloves.

But, if that is really a problem then C is full of punctuation! In that case
use a different language -- or a softer keyboard.
I would suggest an ergonomic keyboard and a better chair. (<http://
www.kinesis-ergo.com/> has some good ones, but for a price)
If you still have these pains also pay a visit to your doctor, do
*NOT* ignore them.
 
B

Ben Bacarisse

MisterE said:
I have seldom seen people use *p. Normally you use only the type definition
itself and try not to use a variable at all. I think this is because some
early compilers would only allow type definitions.

How early, I wonder? The expression form is there in K&R (published
1978). Do we really have to be wary of things that might not get by a
compiler more than 30 years old. Have you every seen one that rejects
this syntax?
All the 'guidelines' at
companies I have coded for always ask to use type definitions only, never
variables.

All that shows is that they are missing a useful feature. I doubt it
has anything to do with compiling with old compilers. Do they also
bad "void" (not there in 1978) and advocate the

f(a)
int a;
{ ... }

style of function definition?
 
B

Bartc

I would suggest an ergonomic keyboard and a better chair. (<http://
www.kinesis-ergo.com/> has some good ones, but for a price)
If you still have these pains also pay a visit to your doctor, do
*NOT* ignore them.

Thanks, but this was many years ago. I no longer spend 10-12 hours a day
programming.

But for anyone else still at risk, then yes take some action.
 
A

aarklon

(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.

I think this program will make things clear

#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
int n;
double x;
struct node* next;
}sn;


int main (void)
{

sn *p,*q = NULL;
sn r;

p = malloc(sizeof(sn));
q = malloc(sizeof(*q));


printf("\n sizeof p = %d", sizeof(p));
printf("\n sizeof *p = %d", sizeof(*p));
printf("\n sizeof q = %d",sizeof(q));
printf("\n sizeof *q = %d",sizeof(*q));
printf("\n sizeof NULL = %d",sizeof(NULL));
printf("\n sizeof r = %d",sizeof(r));

free(p);
free(q);

puts ("");
return (EXIT_SUCCESS);
}
 
R

Richard

MisterE said:
I have seldom seen people use *p. Normally you use only the type
definition

Then you are not a C programmer of much experience. It is infinitely
superior for code maintenance.
 
B

Ben Bacarisse

(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) );
I think this program will make things clear

Sorry, not to me. What does it make clear to you?

printf("\n sizeof p = %d", sizeof(p));
printf("\n sizeof *p = %d", sizeof(*p));
printf("\n sizeof q = %d",sizeof(q));
printf("\n sizeof *q = %d",sizeof(*q));
printf("\n sizeof NULL = %d",sizeof(NULL));
printf("\n sizeof r = %d",sizeof(r));
<snip>

To print sizes with %d, cast the sizeof expression to int. This is
safe since all these sizes will be small. Alternatively use the %zu
format if you have a suitable printf.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Function giving exception 9
malloc and functions 24
Lexical Analysis on C++ 1
simplebinary tree 7
malloc 40
Infinite loop problem in linklist 7
malloc and maximum size 56
Naive Custom Malloc Implementation 8

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top