Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

argv

108 views
Skip to first unread message

ag...@drrob1.com

unread,
Nov 4, 2014, 6:16:42 PM11/4/14
to
I am trying to learn c++ after many years of using modula-2 and more
recently ada. I am attempting this under ubuntu 14.04 amd64 version.

#include <iostream>

int main (int argc, char* argv[]) {
char ch;
ch = argv[argc][0]; // this line gives a seg fault
return 0;
}
I don't understand why I'm getting a seg fault. I am trying to
examine the byte that is supposed to be nullptr, and I'm having a
tough time of it.

To my understanding, the expression argv[argc][0] returns a char.

Why is this wrong?

Thanks

Mr Flibble

unread,
Nov 4, 2014, 6:22:18 PM11/4/14
to
argc is a count of arguments argv[0] to argv[argc-1]. argv[argc] is
array bounds overflow.

/Flibble

red floyd

unread,
Nov 4, 2014, 6:26:40 PM11/4/14
to
It's not array bounds overflow. The value of argv[argc] is well
defined. It's NULL. The issue the OP is seeing is dereferencing
a NULL pointer.



Mr Flibble

unread,
Nov 4, 2014, 6:34:16 PM11/4/14
to
*Logically* it is array bounds overflow if not *physically*.

/Flibble

ag...@drrob1.com

unread,
Nov 4, 2014, 7:40:28 PM11/4/14
to
On Tue, 04 Nov 2014 15:26:26 -0800, red floyd <no....@its.invalid>
wrote:
I am trying to access that value of NULL, not dereference it. How do
I do that?

Ian Collins

unread,
Nov 4, 2014, 7:43:32 PM11/4/14
to
The value of NULL is NULL.

char* ch = argv[argc];

if( ch != nullptr)
the_end_of_the_world_is_nigh();

--
Ian Collins

ag...@drrob1.com

unread,
Nov 4, 2014, 8:06:18 PM11/4/14
to
On Wed, 05 Nov 2014 13:43:20 +1300, Ian Collins <ian-...@hotmail.com>
wrote:
Still not clear to me. NULL pointer has to have a value; I'm assuming
it's zero, as that is what gdb showed me. I know I can assign ch='\0'
which is the same except for type.

Is it possible for me to convert this 0 byte to an int for inspection?
I tried atoi and type casting, but I don't understand this well enough
yet.

Ian Collins

unread,
Nov 4, 2014, 8:18:38 PM11/4/14
to
That's what I did in the test above. There isn't a "0 byte", there is a
NULL pointer, a pointer to nothing, a pointer you can't dereference.

Maybe the confusion is down to ch being a char*? That's not the same
thing as a char with a value of zero.

--
Ian Collins

Reinhardt Behm

unread,
Nov 4, 2014, 9:08:18 PM11/4/14
to
I think you are mixing up the pointers in argv[] and the value pointed to.

Assume you invoke your program name "ab" with parameter "cd"
The OS + C-runtime will have setup argc, argv and storage for the values
pointed to by argv[] when main() is called

Somewhere in memory there is:
'a', 'b', 0, 'c', 'd', 0 These are the values pointed to by argv[]

argc has the value 2
argv[0] contain the address of the byte containing 'a'
argv[1] contain the address of the byte containing 'c'
argv[2] contains a NULL pointer. It points to _nothing_. It might have the
bit pattern 0, but the meaning is "points to nothing".

argv[argc] is NULL (shown by gdb as 0)
argv[argc][0] tries to access that _nothing_ pointed to by argv[2]

This gives the segfault.

--
Reinhardt

Barry Schwarz

unread,
Nov 4, 2014, 11:35:40 PM11/4/14
to
On Tue, 04 Nov 2014 20:05:55 -0500, ag...@drrob1.com wrote:

>Still not clear to me. NULL pointer has to have a value; I'm assuming

A pointer has to have a value. (Pointers with automatic storage class
can be indeterminate but that is not relevant to this discussion.) One
of the values a pointer can have is NULL. (Any attempt to dereference
a NULL pointer, using either * or -> operators, results in undefined
behavior. A seg fault is one of the best manifestations of undefined
behavior because it immediately eliminates any delusions that the code
is working properly.)

>it's zero, as that is what gdb showed me. I know I can assign ch='\0'

NULL is a macro that is usually defined in C++ to be 0 (C tolerates
other definitions). You can test a pointer to see if its value is
NULL with expressions of the form
ptr == NULL
and
ptr != NULL
but that does not mean the bits that make up the pointer are all set
to 0. You normally don't care what the bit pattern is in a pointer
and if you do it is system specific and non-portable. It is the
compiler's job to generate the correct code so the two expressions
evaluate correctly regardless of the bit pattern.

>which is the same except for type.

Setting a char to '\0' has nothing to do with the value of a pointer.

>Is it possible for me to convert this 0 byte to an int for inspection?

You can convert the value of a pointer to an int with the appropriate
cast. It might be better to use intptr_t. In any case, I don't think
the result is guaranteed to be 0 if the pointer happens to be NULL.
But there is no need. The expressions above will always tell you if
the value is or is not NULL.

>I tried atoi and type casting, but I don't understand this well enough
>yet.

As noted, there is no need.

--
Remove del for email

Osmium

unread,
Nov 5, 2014, 8:56:07 AM11/5/14
to
The following link may be helpful, it deals with what I think of as "C
magic" Yes it is C but most of it pertains to C++ as well. I particularly
had in mind NULL, EOF,stdin, stdout, stderr. EOF, in particular, might well
cause you similar problems as you continue the learning process.

Keep in mind that C is case sensitive. Also remember there is an ASCII
character named NUL or something similar to that, but a different thing. And
pervading computer "science" is the *concept* of null, e.g. the last link in
a linked list or a tree element without any children.

As I post this I have read the answers I can see on my server at 13:50 GMT
on Wednesday.

http://icecube.wisc.edu/~dglo/c_class/stdio.html


Geoff

unread,
Nov 5, 2014, 11:40:25 AM11/5/14
to
It's wrong because the /address of/ argv[argc][0] at that time is
NULL. It points to nothing, therefore you can't dereference it.

The pointer doesn't just point to a NUL it _is_ NULL.

The value of a pointer is the value in memory the pointer points to,
the address of the pointer is the address in memory to which it
points.

C makes it the responsibility of the programmer to make sure his
pointers are always valid before he dereferences them.

Barry Schwarz

unread,
Nov 5, 2014, 1:28:17 PM11/5/14
to
On Wed, 05 Nov 2014 08:40:00 -0800, Geoff <ge...@invalid.invalid>
wrote:

>On Tue, 04 Nov 2014 18:16:14 -0500, ag...@drrob1.com wrote:
>
>>I am trying to learn c++ after many years of using modula-2 and more
>>recently ada. I am attempting this under ubuntu 14.04 amd64 version.
>>
>>#include <iostream>
>>
>>int main (int argc, char* argv[]) {
>> char ch;
>> ch = argv[argc][0]; // this line gives a seg fault
>> return 0;
>>}
>>I don't understand why I'm getting a seg fault. I am trying to
>>examine the byte that is supposed to be nullptr, and I'm having a
>>tough time of it.
>>
>>To my understanding, the expression argv[argc][0] returns a char.
>>
>>Why is this wrong?
>>
>
>It's wrong because the /address of/ argv[argc][0] at that time is
>NULL. It points to nothing, therefore you can't dereference it.

Surely you meant the address in argv[argc].

>The pointer doesn't just point to a NUL it _is_ NULL.
>
>The value of a pointer is the value in memory the pointer points to,

The value of a pointer is the address of the memory it points to
except when the value is NULL since in that case it doesn't point to
memory at all. The value pointed to can be obtained by dereferencing
the pointer (applying the [0] operator to the pointer achieves this)
but this is only valid if the pointer actually points to memory.

>the address of the pointer is the address in memory to which it
>points.

The address of a pointer is the address in memory that the pointer
occupies. It is obtained by applying the & operator to the pointer
name.

>C makes it the responsibility of the programmer to make sure his
>pointers are always valid before he dereferences them.

ag...@drrob1.com

unread,
Nov 5, 2014, 6:49:35 PM11/5/14
to
On Tue, 04 Nov 2014 20:35:12 -0800, Barry Schwarz <schw...@dqel.com>
wrote:

>On Tue, 04 Nov 2014 20:05:55 -0500, ag...@drrob1.com wrote:
>
>>Still not clear to me. NULL pointer has to have a value; I'm assuming
>
>NULL is a macro that is usually defined in C++ to be 0 (C tolerates
>other definitions). You can test a pointer to see if its value is
>NULL with expressions of the form
> ptr == NULL
>and
> ptr != NULL
>but that does not mean the bits that make up the pointer are all set
>to 0. You normally don't care what the bit pattern is in a pointer
>and if you do it is system specific and non-portable. It is the
>compiler's job to generate the correct code so the two expressions
>evaluate correctly regardless of the bit pattern.
>
>>which is the same except for type.
>
>Setting a char to '\0' has nothing to do with the value of a pointer.
>
>>Is it possible for me to convert this 0 byte to an int for inspection?
>
>You can convert the value of a pointer to an int with the appropriate
>cast. It might be better to use intptr_t. In any case, I don't think
>the result is guaranteed to be 0 if the pointer happens to be NULL.
>But there is no need. The expressions above will always tell you if
>the value is or is not NULL.
>
>>I tried atoi and type casting, but I don't understand this well enough
>>yet.
>

Thanks, this helped. I was able to do this with a segfault
i = intptr_t ( argv[argc] );

and i has the value of 0.

I guess what I'm having so much trouble with is how pervasive pointers
are in c-ish. Modula-2 and Ada don't do this.

I thought that argv[argc] is just a byte that I could have
interpretted in a different way. I now understand that the compiler
sees this as a pointer type and I cannot easily change that.

Thanks again.
Rob

ag...@drrob1.com

unread,
Nov 5, 2014, 6:50:14 PM11/5/14
to
On Wed, 5 Nov 2014 08:55:43 -0500, "Osmium" <r124c...@comcast.net>
wrote:

><ag...@drrob1.com> wrote:
>
>>I am trying to learn c++ after many years of using modula-2 and more
>> recently ada. I am attempting this under ubuntu 14.04 amd64 version.
>>
>> #include <iostream>
>>
>> int main (int argc, char* argv[]) {
>> char ch;
>> ch = argv[argc][0]; // this line gives a seg fault
>> return 0;
>> }
>> I don't understand why I'm getting a seg fault. I am trying to
>> examine the byte that is supposed to be nullptr, and I'm having a
>> tough time of it.
>>
>
>The following link may be helpful, it deals with what I think of as "C
>magic" Yes it is C but most of it pertains to C++ as well. I particularly
>had in mind NULL, EOF,stdin, stdout, stderr. EOF, in particular, might well
>cause you similar problems as you continue the learning process.
>
>Keep in mind that C is case sensitive. Also remember there is an ASCII
>character named NUL or something similar to that, but a different thing. And
>pervading computer "science" is the *concept* of null, e.g. the last link in
>a linked list or a tree element without any children.
>
>As I post this I have read the answers I can see on my server at 13:50 GMT
>on Wednesday.
>
>http://icecube.wisc.edu/~dglo/c_class/stdio.html
>


That link is helpful. Thanks

Barry Schwarz

unread,
Nov 6, 2014, 12:56:44 AM11/6/14
to
This should not have caused a seg fault since you are not attempting
to dereference the pointer. Evaluating a NULL pointer is perfectly
legal.

But the conversion is completely unnecessary. Everything you can
learn from i can be just as easily, and more efficiently, handled with
the expression
argv[argc] == NULL
and if the concept of NULL is bothering you then you can use the
equivalent
argv[argc] == 0

>and i has the value of 0.

An implementation detail specific to your compiler (also common to
many other compilers) but not guaranteed to be portable.

>I guess what I'm having so much trouble with is how pervasive pointers
>are in c-ish. Modula-2 and Ada don't do this.
>
>I thought that argv[argc] is just a byte that I could have
>interpretted in a different way. I now understand that the compiler
>sees this as a pointer type and I cannot easily change that.

It is the start-up code that gets control before your main function
that passes the arguments to main. It will always pass an int as the
first argument (which convention calls argc but there is nothing
magical about the name). The start-up code also constructs an array of
argc+1 pointers: the first pointer (known as argv[0]) points to an
implementation defined string which identifies the program; the next
argc-1 pointers point to the arguments, if any, from the command line
that was used to invoke the program; and the last pointer (known as
argv[argc]) will be set to NULL. The start-up code passes the address
of the first of these constructed pointers as the second argument.

Geoff

unread,
Nov 6, 2014, 3:33:07 AM11/6/14
to
On Wed, 05 Nov 2014 10:27:59 -0800, Barry Schwarz <schw...@dqel.com>
wrote:

>On Wed, 05 Nov 2014 08:40:00 -0800, Geoff <ge...@invalid.invalid>
>wrote:
>
>>On Tue, 04 Nov 2014 18:16:14 -0500, ag...@drrob1.com wrote:
>>
>>>I am trying to learn c++ after many years of using modula-2 and more
>>>recently ada. I am attempting this under ubuntu 14.04 amd64 version.
>>>
>>>#include <iostream>
>>>
>>>int main (int argc, char* argv[]) {
>>> char ch;
>>> ch = argv[argc][0]; // this line gives a seg fault
>>> return 0;
>>>}
>>>I don't understand why I'm getting a seg fault. I am trying to
>>>examine the byte that is supposed to be nullptr, and I'm having a
>>>tough time of it.
>>>
>>>To my understanding, the expression argv[argc][0] returns a char.
>>>
>>>Why is this wrong?
>>>
>>
>>It's wrong because the /address of/ argv[argc][0] at that time is
>>NULL. It points to nothing, therefore you can't dereference it.
>
>Surely you meant the address in argv[argc].

I mean both. If argv[argc] is NULL, then argv[argc][0], the pointer to
what would be the first member of the argv[argc] array is also NULL,
therefore the dereference of that pointer is a segfault.

If the OP's program is passed no command line arguments then argc == 1
and argv[argc] == NULL, dereferencing it with argv[argc][0] must fail.

[snip]

>
>The address of a pointer is the address in memory that the pointer
>occupies. It is obtained by applying the & operator to the pointer
>name.
>

Quite right. If he had written if(&argv[argc][0] != NULL) ch =
argv[argc][0]; he would have avoided the segfault but that's probably
a little too defensive to suit most c++ programmers and probably not
what the OP is seeking.

Barry Schwarz

unread,
Nov 6, 2014, 5:25:52 AM11/6/14
to
On Thu, 06 Nov 2014 00:32:51 -0800, Geoff <ge...@invalid.invalid>
wrote:

>On Wed, 05 Nov 2014 10:27:59 -0800, Barry Schwarz <schw...@dqel.com>
>wrote:
>
>>On Wed, 05 Nov 2014 08:40:00 -0800, Geoff <ge...@invalid.invalid>
>>wrote:
>>
>>>On Tue, 04 Nov 2014 18:16:14 -0500, ag...@drrob1.com wrote:
>>>
>>>>I am trying to learn c++ after many years of using modula-2 and more
>>>>recently ada. I am attempting this under ubuntu 14.04 amd64 version.
>>>>
>>>>#include <iostream>
>>>>
>>>>int main (int argc, char* argv[]) {
>>>> char ch;
>>>> ch = argv[argc][0]; // this line gives a seg fault
>>>> return 0;
>>>>}
>>>>I don't understand why I'm getting a seg fault. I am trying to
>>>>examine the byte that is supposed to be nullptr, and I'm having a
>>>>tough time of it.
>>>>
>>>>To my understanding, the expression argv[argc][0] returns a char.
>>>>
>>>>Why is this wrong?
>>>>
>>>
>>>It's wrong because the /address of/ argv[argc][0] at that time is
>>>NULL. It points to nothing, therefore you can't dereference it.
>>
>>Surely you meant the address in argv[argc].
>
>I mean both. If argv[argc] is NULL, then argv[argc][0], the pointer to
>what would be the first member of the argv[argc] array is also NULL,
>therefore the dereference of that pointer is a segfault.

Since argv[i] has type char*, it is obvious that argv[i][0] has type
char is not a pointer at all.

>If the OP's program is passed no command line arguments then argc == 1
>and argv[argc] == NULL, dereferencing it with argv[argc][0] must fail.
>
>[snip]
>
>>
>>The address of a pointer is the address in memory that the pointer
>>occupies. It is obtained by applying the & operator to the pointer
>>name.
>>
>
>Quite right. If he had written if(&argv[argc][0] != NULL) ch =
>argv[argc][0]; he would have avoided the segfault but that's probably

No, this would not avoid the seg fault. The [] operator binds more
tightly than the & operator and the expression &argv[argc][0]
evaluates as &(argv[argc][0]) and that involves derefencing argv[argc]
which is NULL and therefore cannot be dereferenced.

>a little too defensive to suit most c++ programmers and probably not
>what the OP is seeking.
>
>>>C makes it the responsibility of the programmer to make sure his
>>>pointers are always valid before he dereferences them.

Rick C. Hodgin

unread,
Nov 6, 2014, 6:08:05 AM11/6/14
to
int main (int argc, char* argv[])
{
char ch;

ch = argv[argc - 1][0];
// this line gives a seg fault return 0;
}

The top ten things I hate most about C/C++:

#9 ... #8 ... ... ... #1 ... #0.

Best regards,
Rick C. Hodgin

Rosario193

unread,
Nov 7, 2014, 4:00:48 PM11/7/14
to
On Tue, 04 Nov 2014 18:16:14 -0500, ag...@drrob1.com wrote:

>I am trying to learn c++ after many years of using modula-2 and more
>recently ada. I am attempting this under ubuntu 14.04 amd64 version.
>
>#include <iostream>
>
>int main (int argc, char* argv[]) {
> char ch;
> ch = argv[argc][0]; // this line gives a seg fault

for me argv[argc]==0 is true...
becouse the ones define the language, if i rememeber well,
define that has to be so

the 0 in "argv[argc]==0" has size of char*

so when you do ch=argv[argc][0]
it is like you do ch=0[0]
that is like you do ch=*0
that can[has to] seg fault [at last here]

Scott Lurndal

unread,
Nov 7, 2014, 4:14:42 PM11/7/14
to
Rosario193 <Ros...@invalid.invalid> writes:
>On Tue, 04 Nov 2014 18:16:14 -0500, ag...@drrob1.com wrote:
>
>>I am trying to learn c++ after many years of using modula-2 and more
>>recently ada. I am attempting this under ubuntu 14.04 amd64 version.
>>
>>#include <iostream>
>>
>>int main (int argc, char* argv[]) {
>> char ch;
>> ch = argv[argc][0]; // this line gives a seg fault
>
>for me argv[argc]==0 is true...
>becouse the ones define the language, if i rememeber well,
>define that has to be so

The C standard (9989:201x) (5.1.2.2.1) requires that:

argv[argc] shall be a null pointer.

I wouldn't rely on it, myself.

Dereferencing a null pointer is undefined. Which is why


>>I don't understand why I'm getting a seg fault. I am trying to
>>examine the byte that is supposed to be nullptr, and I'm having a
>>tough time of it.
>>
>>To my understanding, the expression argv[argc][0] returns a char.

Because you are dereferencing a null pointer. The behavior of that
operation is undefined.

argv[argc] == NULL

scott
0 new messages