Help with pointers :/

Help with pointers :/

Post by gabrie » Mon, 22 Jan 2007 05:15:15


#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int main(int argc, char *argv[])
{
char *x;
x = argv[1];
printf("*x = %s \n", argv[1]);
char *y = argv[1];
printf("*y = %s \n", *y);


}

if i printf %s for the second print statement i get a segment fault.
whereas if i use %c it works fine.

What i'm trying to do is take the parameter passed to the command
located at argv[1] and refer to that from a pointer (after assigning it)
I keep getting seg faults from trying to print as a string.


Please explain very slowly as if to a child. :)
thanks

Gabe
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

Help with pointers :/

Post by Jack Klei » Sat, 27 Jan 2007 18:55:20

On 20 Jan 2007 20:15:15 GMT, gabriel < XXXX@XXXXX.COM > wrote in
comp.lang.c.moderated:

Of course you realize that your program will exhibit undefined
behavior if it is invoked with no command line arguments, because argv
[1] will be a null pointer.

For illustration purposes, let's assume that your program is invoked
with a single command line argument like this:

progname abc

...so that argv[1] will point to "abc".


x now points to the array of chars 'a', 'b', 'c', '\0', which can also
be referred to as the string "abc".


Here you pass argv[1], which is a pointer to character and points to
the string "abc" to printf() with a "%s" conversion specifier. Since
the argument matches "%s" and does point to a valid string, all is
will.


Now y points to the string "abc".


Here you dereference y, to get what it points to. Since y is a
pointer to character, it points to a character, in this case the 'a'
of "abc".

Because of the "%s" conversion specifier, printf() is expecting a
pointer for the argument. You are passing it an int, containing the
numeric value of the character 'a'. printf() is trying to use that
numeric value as a pointer, and access a string of characters at that
address.

But the numeric value of a char, converted to int, is not a pointer.
On some platforms, an int and a pointer to char are bit even the same
size.

When you pass an argument type to printf() that does not match the
conversion specifier, the result is undefined behavior. On your
particular platform, the result of this undefined behavior is a
segment fault.


To make this work correctly, replace "*y" in the printf() call with
just plain 'y':

printf("*y = %s \n", y);

--
Jack Klein
Home: http://www.yqcomputer.com/
FAQs for
comp.lang.c http://www.yqcomputer.com/
comp.lang.c++ http://www.yqcomputer.com/ ++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.yqcomputer.com/ ~ajo/docs/FAQ-acllc.html
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

 
 
 

Help with pointers :/

Post by Kenneth Br » Sat, 27 Jan 2007 18:55:39


[...]

The variable "y" is of type "char *". Therefore, "*y" is of type
"char". Specifically, it's the first character in argv[1]. It is
not a _pointer_ to the first character -- it _is_ the first character.
If you want the string, you want "y", not "*y".

Note how, when you used "%c", you would always get the first character
of the first argument.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto: XXXX@XXXXX.COM >
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

Help with pointers :/

Post by Eric » Sat, 27 Jan 2007 18:56:16


printf("*y = %c \n", *y);
Eric


Eric
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

Help with pointers :/

Post by schwarz » Sat, 27 Jan 2007 18:56:18


argv points to the first of a set of addresses. argv[0] is the first
of these addresses (and "normally" is the address of a string that
contains the program name). argv1 is the second of these addresses and
points to the first command line argument.


You don't want the * as part of the second argument. While it is true
that you are attempting to print what y points to and not the value of
y itself, the fact that you use the %s conversion requires the operand
to be a pointer to char.

This is due to the fact that strings are not a type in C but simply a
convention. A string simply is a sequence of char terminated by a '\0'
and referenced by the address of the first char. Conseqently, even
though %s says print the string, you still pass the address of the
string (address of its first char) rather than the string itself.

Since y is a char*, *y is obviously a char. When you use the %c
conversion, printf happily prints the character that y points to. But
when you use %s, printf interprets the argument as an address. Because
the argument was actually a char, you invoked undefined behavior (your
system probably tried to use the value of the char as an address,
pointing to who knows where in your kernel). Fortunately, on your
system this undefined behavior manifested itself in a fashion that
caused your operating system to abort the program.

--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

Help with pointers :/

Post by Geof » Sat, 27 Jan 2007 18:56:34


You get it right and then you get it wrong and the answer is in the
second line of the function: x = argv[1];

char *argv[] is an array of strings or more properly a pointer to
array(s) of type char, the arguments to the program. The basic
elements of each argument string are type char. You could also think
of this as a multidimensional array where argv[1][0] is the first
character of the string pointed to by argv[1].

x is a pointer to an array of type char. (char *x;) and if x = argv[1]
then x will point to the first element of the argv[1] array.

Your first printf is correct and by substitution the answer to your
problem but it's not *x = but x = thus:

Since x = argv[1] then

printf("x = %s \n", argv[1]);

can be written as

printf("x = %s \n", x);

Next, you mix declaration and assignment and there lies your
confusion. You lose track that char *y is exactly the same declaration
as char *x and therefore should get the same treatment:

Declare char *y at the top of the function where it belongs.
Assign y to argv[1] and then remember that since y points to the first
element of argv[1] making *y a character, not a string.

Your program becomes:

int main(int argc, char *argv[])
{
char *x;
char *y;

x = argv[1];
printf("argv[1] = %s \n", argv[1]);
printf("x = %s \n", x);
y = argv[1];
printf("*y = %c \n", *y);
}

and prints:

argv[1] = abc
x = abc
*y = a
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

Help with pointers :/

Post by Hans-Bernh » Sat, 27 Jan 2007 18:57:01


[...]



And you should consider yourself lucky that you did. The undefined
behaviour caused by this snipped could manifest itself in *much*
better-hidden forms than a brutally obvious segfault.


Of course it did.

Now, to understand, read the descriptions of %s and %c, and search for
differences. What are their required argument types, and what is the
type of the argument you've given?
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

Help with pointers :/

Post by Willer » Sat, 27 Jan 2007 18:57:08


^
Delete this asterisk. It's dereferencing y, so that printf ends up
looking at some random place in memory rather than a known-valid string.


Done, I hope.
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

Help with pointers :/

Post by Kevin Ashl » Sat, 27 Jan 2007 18:57:35


OK....
argv[1] is a pointer to char
y is a pointer to char
x is a pointer to char
%s expects a pointer to char
but *y is ....

Well, what is it ?

(Hint: if z is of type "pointer to mumble", *z is of type "mumble")

--
Kevin Ashley This is not a signature
Head of Digital Archives
ULCC http://www.yqcomputer.com/
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

Help with pointers :/

Post by Walter Bri » Sat, 27 Jan 2007 18:58:48

In message < XXXX@XXXXX.COM > of Sat, 20 Jan 2007
20:15:15 in comp.lang.c.moderated, gabriel < XXXX@XXXXX.COM >
writes

I suggest to the moderator that that posting is probably off topic with
its reference to a "segment fault". I don't believe that term is
standard. However gabriel (sic) does show some ignorance of the language
which is topical. I shall try to reduce that ignorance.


Your program assumes (argc >= 2) for argv[1] to be a string.

Let us assume your program is called foo and you call foo bar arg and
some magic puts "foo" in argv[0], "bar" in argv[1] and "" in argv[2] and
2 into argc.
x is "bar" and can be legitimately interpreted by %s
*y is 'b'. Interpreting 'b' with %s results in undefined behavior which
fortunately results in a segment fault in your system.


I suggest you use a symbolic de *** . Stop at the line
Where you will find y is "bar" and *y is 'b' or 98 if your de *** is
unhelpful - 98 is the numeric value which is the usual encoding of 'b'.

A de *** will often tell you what your code means and the discrepancy
between its meaning and your intention will usually educate you much
more efficiently than can
--
Walter Briscoe
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

Help with pointers :/

Post by Ulrich Eck » Sat, 27 Jan 2007 18:58:52


You aren't using x any further than here.

^^
The text claims something that isn't true.


Above, you pass 'argv[1]' as argument corresponding to a '%s'. Here, you
pass '*y', with 'y=argv[1]', so effectively that is '*argv[1]'. Remember,
strings in C are stored as a pointer to their first character.


Well, you do pass a char, not a string.


Well, first thing you should do is make sure that the argument really
exists, i.e. check that 'argc>1'. Then, unless you plan to modify it, you
should use a 'char const*' - if you accidentally modify it the compiler
will tell you.

Uli
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.