when I was testing double pointer behaviour I got a result that I don't understand well.
==> code 1 :
int main (int argc , char **argv)
{
if(*argv+1 ==NULL)
{
printf("NULL pointer \n");
exit(0) ;
}
else
{
printf("test double pointer[] : %s \n ",*argv+1);
}
return(0);
}
====> result 1
root@root:/home/aa/test# ./geip 1255
test double pointer[] : /geip
root@root:/home/aa/test#
===> code 2 :
int main (int argc , char **argv)
{
if(*argv+9 ==NULL)
{
printf("NULL pointer \n");
exit(0) ;
}
else
{
printf("test double pointer[] : %s \n ",*argv+9);
}
return(0);
}
==> result 2 :
root@root:/home/aa/test# ./geip 1255
test double pointer[] : 55
root@root:/home/aa/test#
==> result 3 :
root@root:/home/aa/test# ./geip
test double pointer[] : ELL=/bin/bash
root@root:/home/aa/test#
it seems that printf display from n th word (1 and 9) how we can explain this behaviour of pointer ?
You're using it wrong.
*argv+1
will be interpreted as (argv[0])+1
and since argv[0]
is "./geip" you get "/geip".
*argv+9
will be interpreted as (argv[0])+9
but since argv[0]
only has length 6 the outcome is undefined.
In your case, argv is probably stored as :
. / g e i p \0 1 2 5 5 \0
0 1 2 3 4 5 6 7 8 9 10 11
Which explains why +9
gets you "55"
But you should really forget that because it's never going to be useful! This is undefined behavior and should not ever be used.
char **argv
is a pointer to a char *
(sometimes referred to more simply as a string). You dereference this pointer when you do *argv
. The result of this dereference is a char *
or in other words it is the address of a char
. When you do addition with the result, your code is computing a new address. So, for example while *argv
would be the address of the first character in your string, *argv+1
is the address of the second character in your string.
When you add in a number that is longer than the length of your string you are stepping out of "safety". Remember that C will let you do pointer arithmetic that takes you past the end of your string. In your second example you are asking printf to go 9 bytes past the start of *argv
and print characters from there to the next \\0
(or NULL) byte. You are effectively reading arbitrary memory from your program's process space, which explains what is being printed.
There are actually more than one problem.
*argv + 9
) means literally: "defeference argv and move pointer 9 chars", and really, if you move 9 characters from ./geip 1255
you'll arrive to 55
. So either use argv[i]
( i = 1..N
denotes argument index) or if you want to do it the hard way, you must add parentheses: *(argv + i)
. For example when you run ./geip abc 123
:
argv[0]
is string
holding program name - ./geip
argv[1]
is string
holding the first argument - a
argv[2]
is string
holding the second argument - b
argv[3]
is string
holding the third argument - c
argv[4]
is string
holding the fourth argument - 123
argv[5]
is NULL as argc will bw 5
(see comments) argv[>5]
is not a good idea, because there are no more arguments. So you better check argc
to see how many arguments there are. You just do a pointer arithmetics: **argv is a pointer to list of pointers *argv is a head of the list
//char **argv is given from outthere
char *p;
p = *argv; // the same as "p = *argv[0]"
for (int i = 0; i < 100) {
printf("Next: %s\n", p+i);
}
Try to run it and see the dump of memory, from head of the list to next 100 bytes.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.