pointer dereference

S

somenath

Hi All,
I have one doubt regarding pointer .I have one small code as
mentioned bellow .

#include<stdio.h>
#include<stdlib.h>
int main (void)
{
int *p;
int *ptr= malloc(sizeof(int *));
return 0;
}
My doubt is if (sizeof(int *)); is undefined ? Because "p" is point
to any where .So when I try to dereference will it show undefined
behavior ?. I was expatiating it will crash .But in gcc version 3.2.2
20030222 (Red Hat Linux 3.2.2-5) not crashing .

Regards,
Somanath
 
A

Anurag

Hi All,
I have one doubt regarding pointer .I have one small code as
mentioned bellow .

#include<stdio.h>
#include<stdlib.h>
int main (void)
{
int *p;
int *ptr= malloc(sizeof(int *));
return 0;}

My doubt is if (sizeof(int *)); is undefined ? Because "p" is point
to any where .So when I try to dereference will it show undefined
behavior ?. I was expatiating it will crash .But in gcc version 3.2.2
20030222 (Red Hat Linux 3.2.2-5) not crashing .

Regards,
Somanath

Here malloc allocate memory for int * which is 2 byte thus program not
crashes, here sizeof(int *) is not undefined it is 2 byte.
 
M

mark_bluemel

Hi All,
I have one doubt regarding pointer .I have one small code as
mentioned bellow .

#include<stdio.h>
#include<stdlib.h>
int main (void)
{
int *p;

You don't do anything with this.
int *ptr= malloc(sizeof(int *));

malloc returned the address of a region of memory suitable to hold a
pointer to integer.

You have put that address in a pointer to integer, not a pointer to
pointer to integer.

Logically you should have declared "int **ptr = malloc(sizeof(int
*));"
return 0;}

My doubt is if (sizeof(int *)); is undefined ?

"int *" is a valid data type, with a known size. Why would this be
undefined?
Because "p" is point
to any where .So when I try to dereference will it show undefined
behavior ?.

What has "p" got to do with anything here? You don't do anything with
"p" at all in this sample code - certainly not dereference it.
I was expatiating it will crash .

So you weren't expecting undefined behaviour :)

This is a particularly confusing post - the sample code is totally
pointless. What were you actually trying to understand when you wrote
it?
 
M

mark_bluemel

Here malloc allocate memory for int *
True

which is 2 byte

Not necessarily - it's not 2 bytes on any machine I work with. (If
you're interested, and you need not be, it's 4 bytes on some and 8
bytes on some others).
thus program not
crashes, here sizeof(int *) is not undefined it is 2 byte.

No it's sizeof(int *) whatever that size might be for a particular
implementation.

If sizeof(int *) wasn't "defined" the program would not have compiled.
Crashing is not relevant to this question.
 
S

santosh

Anurag said:
Here malloc allocate memory for int * which is 2 byte thus program not
crashes, here sizeof(int *) is not undefined it is 2 byte.

Maybe "there", but do note that the size of a pointer to int is
implementation dependant, just like for other pointer and most other
object types. For example on a machine over here, a pointer to int is
four bytes in size; on yet another 64-bit machine it's eight bytes in
size...

The C Standard only makes limited guarantees about the width and range
of it's types. They are:

* A char is always one byte by definition and has to be at least eight
value bits in size.
* The relationship:
char <= short <= int <= long <= long long
should be honoured.
* A long must be at least 32 bits.
* A long long must be at least 64 bits.
* The size_t type should be able to hold the size, (in bytes), of at
least one largest possible object
that can be created by the implementation.
* A pointer of type void should be able to hold the highest possible
address of the program's
address space.
 
S

santosh

somenath said:
Hi All,
I have one doubt regarding pointer .I have one small code as
mentioned bellow .

#include<stdio.h>
#include<stdlib.h>
int main (void)
{
int *p;
int *ptr= malloc(sizeof(int *));

Here you're storing the address of a single dynamically allocated
pointer to type int into another pointer to type int. A pointer to
type T is meant to hold the address of an array of objects of type T.
In other words a pointer to type int should hold the address of an
array of type int, not an array of type pointer to int. To do the
latter, you should use a pointer to pointer to int.

int **ptr = malloc(sizeof *ptr);
or
int **ptr = malloc(sizeof(int *));
return 0;
}
My doubt is if (sizeof(int *)); is undefined ?

It's implementation defined, i.e. each implementation must define it.
It cannot be undefined, though it's definition can vary between
implementations.
Because "p" is point
to any where .So when I try to dereference will it show undefined
behavior ?. I was expatiating it will crash .But in gcc version 3.2.2
20030222 (Red Hat Linux 3.2.2-5) not crashing .

You don't use 'p' in your code snippet at all.
 
R

Richard Heathfield

santosh said:

The C Standard only makes limited guarantees about the width and range
of it's types. They are:

* A char is always one byte by definition and has to be at least eight
value bits in size.
* The relationship:
char <= short <= int <= long <= long long
should be honoured.

It isn't quite as simple as that, actually, although in non-pathological
implementations the above rule of thumb works just fine. Nevertheless,
the potential for padding bits means that a short could actually be
wider than an int, and an int could be wider than a long, and so on.

Also, even if we're talking about ranges rather than sizes, your rule of
thumb still doesn't quite cover all the bases. Consider, for example,
an implementation where all types are 64 bits and char is unsigned. In
such a circumstance, UCHAR_MAX would exceed SHRT_MAX, and it would be
quite possible for char to be able to represent one value /more/ than
short.

* A pointer of type void should be able to hold the highest possible
address of the program's address space.

A pointer of type void *, actually. A value of type void can't hold
anything. One might reasonably claim, I think, that values of type void
can't exist, although I can see a counter-argument regarding
expressions such as (void)foo(), which some people use to persuade lint
programs not to nag them about ignoring return values.
 
S

santosh

Richard said:
santosh said:



It isn't quite as simple as that, actually, although in non-pathological
implementations the above rule of thumb works just fine. Nevertheless,
the potential for padding bits means that a short could actually be
wider than an int, and an int could be wider than a long, and so on.

Also, even if we're talking about ranges rather than sizes, your rule of
thumb still doesn't quite cover all the bases. Consider, for example,
an implementation where all types are 64 bits and char is unsigned. In
such a circumstance, UCHAR_MAX would exceed SHRT_MAX, and it would be
quite possible for char to be able to represent one value /more/ than
short.

Thanks. I knew when I wrote that point, that holes would be picked on
it like on a Swiss cheese. :)
A pointer of type void *, actually. A value of type void can't hold
anything. One might reasonably claim, I think, that values of type void
can't exist, although I can see a counter-argument regarding
expressions such as (void)foo(), which some people use to persuade lint
programs not to nag them about ignoring return values.

Maybe this is a language issue. Would I be correct when I say "A
pointer to type void"? I don't think so. So I suppose instead of
saying, for example, "a pointer to type int", I should say "a pointer
of type int *" or, better yet, "an int pointer"...?
 
C

Chris Dollin

Richard said:
A pointer of type void *, actually. A value of type void can't hold
anything. One might reasonably claim, I think, that values of type void
can't exist,

I think it's more reasonable to claim that there's exactly one value of
type void -- we could call it, oh I dunno, sponk or flolo or `unit` -- which
is conveniently represented with zero bits. (Not bits that are zero, of
course.)

I know the standard talks about "an incomplete type that can never be
completed". It looks like the long way round the houses to me, but I
wasn't there: maybe there really is a ditch in front of Howard's house
as well as a marching band in the street.

--
RIP Donald Michie 11 November 1923 - 7 July 2007

"ARCHER IS WATCHING YOU."

Hewlett-Packard Limited Cain Road, Bracknell, registered no:
registered office: Berks RG12 1HN 690597 England
 
S

somenath

Hi All,
I have one doubt regarding pointer .I have one small code as
mentioned bellow .

#include<stdio.h>
#include<stdlib.h>
int main (void)
{
int *p;
int *ptr= malloc(sizeof(int *));
return 0;}

My doubt is if (sizeof(int *)); is undefined ? Because "p" is point
to any where .So when I try to dereference will it show undefined
behavior ?. I was expatiating it will crash .But in gcc version 3.2.2
20030222 (Red Hat Linux 3.2.2-5) not crashing .

Regards,
Somanath

Hi All,
Sorry for the mistake.By mistake i copied int *ptr= malloc(sizeof(int
*));.My intention was to write " int *ptr=
malloc(sizeof(*p));" .Should it have undefined behavour?
 
R

Richard Bos

Sorry for the mistake.By mistake i copied int *ptr= malloc(sizeof(int
*));.My intention was to write " int *ptr=
malloc(sizeof(*p));" .Should it have undefined behavour?

You mean, your code would be

#include<stdio.h>
#include<stdlib.h>
int main (void)
{
int *p;
int *ptr= malloc(sizeof *p);
return 0;
}

No, that does not have undefined behaviour, because in the context of
sizeof, *p is not evaluated. sizeof does not evaluate its operand,
simply because there is no need for it to. The size of *p is the size of
an int, no matter what value (or garbage) p actually contains.
(There is one exception to this rule, which involves variable-length
arrays. But that's a C99 problem only. It doesn't apply to your code.)

BTW, it is probably better to write
int *ptr= malloc(sizeof *ptr);
instead, because then you know that ptr will always point at memory
large enough to contain one of what ptr should point at, even if you
later change the type of p or ptr.

Richard
 
S

santosh

somenath said:
Hi All,
Sorry for the mistake.By mistake i copied int *ptr= malloc(sizeof(int
*));.My intention was to write " int *ptr=
malloc(sizeof(*p));" .Should it have undefined behavour?

No, it shouldn't. ptr is an int pointer. sizeof *p yields the size of
the type pointed to by p. p is an int pointer, so, within the context
of sizeof, *p resolves to an int. So you're assigning the result of a
call to malloc with a request to allocate space for a single int
object. If malloc fails, it'll return a null pointer, which you should
check for. If it succeeds ptr points to an int object.

What did you think could be undefined about the statement?
 
C

Christopher Benson-Manica

Richard Bos said:
BTW, it is probably better to write
int *ptr= malloc(sizeof *ptr);
instead, because then you know that ptr will always point at memory
large enough to contain one of what ptr should point at, even if you
later change the type of p or ptr.
^

Nit: There's no longer any 'p' involved with the above code, which is
undoubtedly part of the reason to prefer it.
 
C

Christopher Benson-Manica

Chris Dollin said:
I think it's more reasonable to claim that there's exactly one value of
type void -- we could call it, oh I dunno, sponk or flolo or `unit` -- which
is conveniently represented with zero bits. (Not bits that are zero, of
course.)

It seems like that value could be called "the null value" without too
much confusion (no more, or less, than with the common term "the
null character"). That said, I read n869 6.2.5 p18 - "The void type
comprises an empty set of values..." - as explicitly contradicting the
notion of there being any values of type void.
 
C

Chris Dollin

Christopher said:
It seems like that value could be called "the null value" without too
much confusion (no more, or less, than with the common term "the
null character"). That said, I read n869 6.2.5 p18 - "The void type
comprises an empty set of values..." - as explicitly contradicting the
notion of there being any values of type void.

I think it's more reasonable to claim that there's exactly one value of
type void -- ie, I think that the Standard's statement otherwise is
a less-optimal choice. But this is discussion about the Standard rather
than the language it defines ...
 
M

mark_bluemel

Hi All,
Sorry for the mistake.By mistake i copied int *ptr= malloc(sizeof(int
*));.My intention was to write " int *ptr=
malloc(sizeof(*p));" .Should it have undefined behavour?

No. I think your problem here is you don't understand that, with the
exception of variable length arrays (a special case), sizeof() doesn't
involve evaluating its argument. Note that although it looks like a
function, sizeof() is an _operator_.

In fact, sizeof will be dealt with at compile time rather than runtime
(again with the exception of VLAs), as all the relevant information
will be available at that point.

The compiler knows in your case that p is a pointer to int, so also it
knows the general expression "*p" is of type int and hence has the
size appropriate to ints on your platform.

By the time you have a runnable program, your sizeof() will have been
resolved to a constant integer value of type "size_t" (again VLAs are
a special case as their size is set at runtime).
 
R

Richard Heathfield

santosh said:
Richard said:
santosh said:
* A pointer of type void should be able to hold the highest
possible
address of the program's address space.

A pointer of type void *, actually. [...]

Maybe this is a language issue. Would I be correct when I say "A
pointer to type void"? I don't think so.

Better: "a pointer of type void *"
So I suppose instead of
saying, for example, "a pointer to type int", I should say "a pointer
of type int *" or, better yet, "an int pointer"...?

Either works. Personally I prefer the "a pointer of type <type>" style,
but "a <type> pointer" is also correct.
 
K

Keith Thompson

santosh said:
Maybe this is a language issue. Would I be correct when I say "A
pointer to type void"? I don't think so. So I suppose instead of
saying, for example, "a pointer to type int", I should say "a pointer
of type int *" or, better yet, "an int pointer"...?

In my opinion, "a pointer to type void" or "a pointer to type int" is
ok, but "a pointer of type void*" or "a pointer of type int*" is
better. Pointer objects don't point to types, they point to objects.
Pointer types don't point to anything, but objects and values of
pointer types may point to objects. But we can colloquially say that
type int* points to type int; it's not 100% accurate, but it's not
ambiguous, and I wouldn't complain about the usage unless I was
invited to.

I wouldn't use the phrase "an int pointer" because it could imply
something that's both an int and a pointer, rather than something that
points to an int.
 
K

Keith Thompson

Chris Dollin said:
I think it's more reasonable to claim that there's exactly one value of
type void -- ie, I think that the Standard's statement otherwise is
a less-optimal choice. But this is discussion about the Standard rather
than the language it defines ...

I disagree; I think it would be unreasonable to say that there's a
value of type void.

Why can't you write this?

void *p = /* whatever */
void obj = *p;
void func(void);
obj = func();

If we say that type void has no values, the answer is obvious. If we
say it has one value, we need special-case rules to say that we can't
use that value, and that sizeof(void) is not 0 but a constraint
violation.
 

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

Array of structs function pointer 10
pointer vs pointer to pointer 4
pointer dereference 12
Fibonacci 0
pointer arithmetic question. 10
pointer array 5
Adding adressing of IPv6 to program 1
Decrement a given pointer. 49

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,229
Latest member
GloryAngul

Latest Threads

Top