allocating memory for pointee

B

Bill Cunningham

I have been trying to understand dereferncing better and came across a
tutorial that showed this.

int *x;
pointer allocated /does that allocate memory for an int/
or do I need to add this?

x=malloc(sizeof(int));

I've never worked knowledgably with this. And if I set the pointer to a
value, I wouldn't need malloc right?

int *x;
int y=42;
x=&y;
No malloc needed for x or y right? I've never needed it before.

Bill
 
L

Lew Pitcher

I have been trying to understand dereferncing better and came across a
tutorial that showed this.

int *x;
pointer allocated /does that allocate memory for an int/
or do I need to add this?

No,
int *x;
does not allocate space for the "pointee". It only allocates space for
the "pointer".
x=malloc(sizeof(int));

Yes, that will now allocate space for the "pointee", and initialize
the "pointer" to point at the "pointee"
I've never worked knowledgably with this. And if I set the pointer to a
value, I wouldn't need malloc right?

Not always.
You can take the address of an int, and give that value to the "pointer".
int *x;
int y=42;
x=&y;

So far, so good. You take the address of y, which is an int, and use that as
the "pointee" to set the pointer x to.
 
L

Lanarcam

Le 16/01/2013 22:16, Bill Cunningham a écrit :
I have been trying to understand dereferncing better and came across a
tutorial that showed this.

int *x;
pointer allocated /does that allocate memory for an int/

No, it doesn't. (It allocates memory for x which is a pointer but
not for the int which it points to)
or do I need to add this?

x=malloc(sizeof(int));

That's a possibility, but normally, you should check the return of
malloc.
I've never worked knowledgably with this. And if I set the pointer to a
value, I wouldn't need malloc right?

int *x;
int y=42;
x=&y;
No malloc needed for x or y right? I've never needed it before.

Right.
 
S

Shao Miller

I have been trying to understand dereferncing better and came across a
tutorial that showed this.

int *x;
pointer allocated /does that allocate memory for an int/
or do I need to add this?

x=malloc(sizeof(int));

Or you could add this:

x = malloc(sizeof *x);

That is a touch more precise than the former, because it says "Try to
allocate enough storage for the pointee of 'x'," rather than "try to
allocate enough storage for an 'int'" (which so happens to be the right
amount of storage).

Using this form, if you decide to change 'int *x;' to 'long *x;' some
day, you don't need to change the line with the 'malloc'.
 
B

Bill Cunningham

Shao said:
Or you could add this:

x = malloc(sizeof *x);

That is a touch more precise than the former, because it says "Try to
allocate enough storage for the pointee of 'x'," rather than "try to
allocate enough storage for an 'int'" (which so happens to be the
right amount of storage).

Using this form, if you decide to change 'int *x;' to 'long *x;' some
day, you don't need to change the line with the 'malloc'.

Oh I see yes. That makes sense. Is that proper style here?

Bill
 
B

Bill Cunningham

<snip>

Does the * in front of the x indicate that x is a pointer? You do not want
just x then or the compiler wouldn't know it's a pointer?
 
S

Shao Miller

<snip>

Does the * in front of the x indicate that x is a pointer? You do not want
just x then or the compiler wouldn't know it's a pointer?

There are two kinds of '*' operator:

- The unary indirection operator
- The binary multiplication operator

the one that's being used above is the unary indirection operator. For
any expression 'E' that has a pointer type, the expression '*E' means:
The pointee of 'E'.

Your declaration of 'x' was:

int *x;

So in a later expression, 'x' has a pointer type. Thus, the expression
'*x' means: The pointee of 'x'.

So 'sizeof *x' means: The size of the pointee of 'x'.

'*x' doesn't tell the compiler that 'x' is a pointer. Your declaration
of 'x' told the compiler that 'x' is a pointer.
 
B

Bill Cunningham

Shao said:
There are two kinds of '*' operator:

- The unary indirection operator
- The binary multiplication operator

the one that's being used above is the unary indirection operator. For any
expression 'E' that has a pointer type, the expression '*E'
means: The pointee of 'E'.

Your declaration of 'x' was:

int *x;

So in a later expression, 'x' has a pointer type. Thus, the
expression '*x' means: The pointee of 'x'.

So 'sizeof *x' means: The size of the pointee of 'x'.

'*x' doesn't tell the compiler that 'x' is a pointer. Your
declaration of 'x' told the compiler that 'x' is a pointer.

So for a function that takes a pointer you don't need to pass that *
operator right?

void func(void *);
would be void func(x); for example. I know you could also use

void func(&x);
And bypass the pointer altogether and pass the object pointed to (pointee)
right?

Bill
 
S

Shao Miller

So for a function that takes a pointer you don't need to pass that *
operator right?

You don't pass an operator, ever.
void func(void *);
would be void func(x); for example. I know you could also use

void func(&x);
And bypass the pointer altogether and pass the object pointed to (pointee)
right?

That second one is not C, so you're mistaken.
 
B

Barry Schwarz

<snip>

Does the * in front of the x indicate that x is a pointer? You do not want
just x then or the compiler wouldn't know it's a pointer?

There is a difference in meaning between the use of the * in a
declaration and in a statement.

In a declaration such as
int *y;
the * indicates that y is indeed a pointer.

In a statement such as you quoted, the * is the unary indirection
operator. This operator requires that its operand be a pointer but it
does not mean that the operand is a pointer. If you mistakenly apply
this operator to a non-pointer operand, it does not magically make the
operand a pointer. Instead you have a syntax error.

And of course you also have to distinguish between the unary
indirection operator and the binary multiplication operator.

Consider
int a = 1;
int b = 2;
int *p = &a;
int c = b * *p;
All three asterisks mean something different.
 
A

Andrey Tarasevich

Oh I see yes. That makes sense. Is that proper style here?

It is just one possible style. And a good one at that. In general I
would prefer to make my code as type-independent as possible. I.e. the
guideline I'd follow is that type names belong in declarations. If
something is not a declaration, it is best to avoid any explicit
references to type names as much as possible.

Under this guideline this is "bad"

x = (int *) malloc(n * sizeof(int));

and this is "good"

x = malloc(n * sizeof *x);

But in the end it is matter of your personal preference.
 
B

Bill Cunningham

Shao said:
You don't pass an operator, ever.


That second one is not C, so you're mistaken.

In the example of scanf which takes a pointer I am thinking you use the
& operator. What's the difference with the second example I gave?

Bill
 
B

Bill Cunningham

Barry said:
There is a difference in meaning between the use of the * in a
declaration and in a statement.

In a declaration such as
int *y;
the * indicates that y is indeed a pointer.

In a statement such as you quoted, the * is the unary indirection
operator. This operator requires that its operand be a pointer but it
does not mean that the operand is a pointer. If you mistakenly apply
this operator to a non-pointer operand, it does not magically make the
operand a pointer. Instead you have a syntax error.

And of course you also have to distinguish between the unary
indirection operator and the binary multiplication operator.

Consider
int a = 1;
int b = 2;
int *p = &a;
int c = b * *p;
All three asterisks mean something different.

What I seem to be confused about is when the unary operator is needed
and when it isn't.

FILE *fp;
fp=fopen()...
not *fp=fopen()...
And in the example I Shao gave,

x=malloc(sizeof *x);
x=malloc(sizeof x); WRONG

Bill
 
S

Shao Miller

In the example of scanf which takes a pointer I am thinking you use the
& operator. What's the difference with the second example I gave?

'void func(&x);' is a syntax violation. It starts out looking like a
function declaration, but isn't one.
 
S

Shao Miller

What I seem to be confused about is when the unary operator is needed
and when it isn't.

FILE *fp;
fp=fopen()...
not *fp=fopen()...
And in the example I Shao gave,

x=malloc(sizeof *x);
x=malloc(sizeof x); WRONG

The meaning of '*' depends on the context. It can be part of a pointer
declarator, or can be one of two possible operators used in an
expression. The unary indirection operator is needed when you wish to
designate the pointee of a pointer.
 
B

Barry Schwarz

Barry Schwarz wrote:
snip


What I seem to be confused about is when the unary operator is needed
and when it isn't.

FILE *fp;
fp=fopen()...
not *fp=fopen()...
And in the example I Shao gave,

x=malloc(sizeof *x);
x=malloc(sizeof x); WRONG

You use the name of the pointer when the pointer is what your code is
dealing with. You code the * to dereference the pointer when the
object pointed to is what your code is dealing with.

When you allocate space, the size of the object that will occupy the
space is what is important, not the size of the pointer that points to
that space.

Consider the case where x is pointer to struct and the structure
contains a dozen int. On a 32 bit system, the size of the pointer
will usually be 4. The size of the structure will be 48.

If you code the syntactically correct but logically incorrect
x = malloc(sizeof x);
it will only allocate 4 bytes. You will never be able to fit your
structure into that small a space. If you code
x = malloc(sizeof *x);
you are telling the system to reserve enough space for the object that
will eventually occupy that space.
 

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

Members online

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top