For Programmers: Free Programming Magazines  


Home > Archive > C > February 2006 > Re: Help in c pointers









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Re: Help in c pointers
Kenneth Brody

2006-02-28, 6:55 pm

"manochavishal@gmail.com" wrote:
>
> HI
>
> int *p;
> *p = 4;
>
> char * msg;
> *msg = 'c';
>
> printf("msg is %s",msg);
>
> when i try to pass a value 4 to place what integer pointer p points to
> it says seg fault
>
> but for the char pointer it works fine.
>
> Why this behaviour


Neither pointer has been initialized, and both assignments invoke UB. In
your particular case, the address in p happened to be invalid for an int,
and the address in msg happened to be valid for a char, and didn't cause
any noticable effect by overwriting that memory.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:ThisIsASpamTrap@gmail.com>


Jordan Abel

2006-02-28, 6:55 pm

On 2006-02-28, Kenneth Brody <kenbrody@spamcop.net> wrote:
> "manochavishal@gmail.com" wrote:
>
> Neither pointer has been initialized, and both assignments invoke UB. In
> your particular case, the address in p happened to be invalid for an int,
> and the address in msg happened to be valid for a char, and didn't cause
> any noticable effect by overwriting that memory.


Incidentally, there's a third instance of undefined behavior here -
anyone know what it is?
Pedro Graca

2006-02-28, 6:56 pm

Jordan Abel wrote:
> On 2006-02-28, Kenneth Brody <kenbrody@spamcop.net> wrote:
>
> Incidentally, there's a third instance of undefined behavior here -
> anyone know what it is?


a) `msg' isn't (*) a c-string (a sequence of chars ending in NUL) so
passing it to printf invokes UB.

b) printf doesn't end with a newline nor is followed by a
fflush(stdout); invoking implementation defined behaviour (???)


(*) probably it is -- there probably is a nul between msg and msg+<some
large integer value>.

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Jordan Abel

2006-02-28, 6:56 pm

On 2006-02-28, Pedro Graca <hexkid@dodgeit.com> wrote:
> Jordan Abel wrote:
>
> a) `msg' isn't (*) a c-string (a sequence of chars ending in NUL) so
> passing it to printf invokes UB.


Not quite - msg isn't a valid pointer at all, so the act itself of
passing it to printf invokes UB. It would equally invoke UB if it were a
void * and being passed to a printf %p format.

The value of msg is indeterminate since it is never initialized. Reading
an indeterminate value results in undefined behavior [since it may be a
trap representation]
Pedro Graca

2006-02-28, 6:56 pm

Jordan Abel wrote:
> On 2006-02-28, Pedro Graca <hexkid@dodgeit.com> wrote:
>
> Not quite - msg isn't a valid pointer at all, so the act itself of
> passing it to printf invokes UB. It would equally invoke UB if it were a
> void * and being passed to a printf %p format.


I understand.

But another question gets raised in my head:
What is a valid pointer?


Examples:

char * p; /* p is, for now, an invalid pointer */

p = &p; /* and now??? */
p = (char*)&p; /* and now??? */
p = main;
p = (char*)main;
p = rand();
p = (char*)rand();


--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Keith Thompson

2006-02-28, 6:56 pm

Pedro Graca <hexkid@dodgeit.com> writes:
[...]
> But another question gets raised in my head:
> What is a valid pointer?
>
>
> Examples:
>
> char * p; /* p is, for now, an invalid pointer */
>
> p = &p; /* and now??? */
> p = (char*)&p; /* and now??? */


In the above two cases, p is a valid pointer; it points to the first
byte of p.

> p = main;


Illegal. A conversion from a pointer-to-function type to a
pointer-to-object type requires a cast.

> p = (char*)main;


Legal (I think), but undefined. The language does not define the
semantics of a conversion from a pointer-to-function type to a
pointer-to-object type.

> p = rand();


Illegal. There is no implicit conversion from int to char*; a cast is
required.

> p = (char*)rand();


This is legal, but the result of converting an int value to char* is
implementation-defined (except for the special case of a null pointer
constant). The value of p may or may not be valid.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Pedro Graca

2006-02-28, 9:55 pm

[Jordan's comment on passing an invalid pointer to printf inserted]

Keith Thompson wrote:
> Pedro Graca <hexkid@dodgeit.com> writes:




[color=darkred]
[snip examples][color=darkred]
>
> This is legal, but the result of converting an int value to char* is
> implementation-defined (except for the special case of a null pointer
> constant). The value of p may or may not be valid.
>


So the following code does not invoke UB?

char * p;
p = (char*)rand();
printf("%c\n", p);

.... and removing the assignment does?

char * p;
printf("%c\n", p);


--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Keith Thompson

2006-02-28, 9:55 pm

Pedro Graca <hexkid@dodgeit.com> writes:
> [Jordan's comment on passing an invalid pointer to printf inserted]
>
> Keith Thompson wrote:
>
>
>
>
> [snip examples]
>
> So the following code does not invoke UB?
>
> char * p;
> p = (char*)rand();
> printf("%c\n", p);


You need "%p", not "%c". Actually, the "%p" format expects a void*;
you can almost certainly get away with passing a char* instead, but
IMHO it's better style to convert it:

printf("%p\n", (void*)p);

C99 6.3.2.3p5:

An integer may be converted to any pointer type. Except as
previously specified, the result is implementation-defined, might
not be correctly aligned, might not point to an entity of the
referenced type, and might be a trap representation.

The "previously specified" part refers to null pointer constants.
Alignment shouldn't be an issue for char*, but you could still get a
trap representation. If so, evaluating p, whether you then pass the
value to printf() or not, invokes undefined behavior.

> ... and removing the assignment does?
>
> char * p;
> printf("%c\n", p);


That certainly invokes UB, even with "%p".

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com