Page 1 of 1

Quick C pointer question

Posted: Tue Jan 17, 2006 11:19 pm
by Neo
What is wrong with this?

Code: Select all

char *var1;
var1="test1";
printf("%d, %s",var1,var1); // is correct
printf("%s",*var1); // crashes why??

Re:Quick C pointer question

Posted: Tue Jan 17, 2006 11:39 pm
by Solar
*var1 is a dereference of a char * - i.e., a char. *var1 is equivalent to 't' - which is of type char, not string.

Re:Quick C pointer question

Posted: Tue Jan 17, 2006 11:41 pm
by Candy
Neo wrote: What is wrong with this?

Code: Select all

char *var1;
var1="test1";
printf("%d, %s",var1,var1); // is correct
printf("%s",*var1); // crashes why??
var1 is a pointer. %d prints the value of the parameter, %s prints the contents (IE, it dereferences). The first printf thus prints the pointer and its content. The second takes the content of the pointer and tries to dereference that, which isn't a pointer. So, it crashes, since "test" is't a valid pointer when cast to a char *.

Re:Quick C pointer question

Posted: Thu Jan 19, 2006 9:32 am
by Pype.Clicker
somewhere in memory, you have written the bytes 't' 'e' 's' 't' '1' and then a null character. Let's say that's at address X.

When you write

Code: Select all

char *var1="test1";
the variable 'var1' contains the value X and the compiler is told that this is a pointer to a char.

Code: Select all

char t = *var1;
would for dereference that pointer -- e.g. generated code would read the value of 'var1' (that is, X), and lookup for a byte at address X.

You'll note that if you do [tt]printf("%d",*var1);[/tt], you'll get the ASCII value for character 't'. You'll note - too - that if you do [tt]printf("%c",*var1);[/tt], you'll get 't' character displayed.

That's precisely what [tt]printf[/tt] does when you ask it to print "%s",var1: it receives the value X as argument, and reads bytes from address X, X+1, X+2 ... until it encounters a null byte.

Now, when you request [tt]printf("%s", *var1)[/tt], you extract the first character of the string, and gives its ASCII value as an address Y that printf will use to get bytes to be printed... not quite good, all you could get would be random garbage -- or more likely a segmentation fault on any dever-friendly system.

note that gcc -Wall would probably shout at you if you attempt such horrors:

Code: Select all

/home/pype> gcc -Wall -c test.c 
test.c: In function 'test':
test.c:9: warning: format '%d' expects type 'int', but argument 2 has type 'char *'
test.c:10: warning: format '%s' expects type 'char *', but argument 2 has type 'int'