By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,137 Members | 2,209 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,137 IT Pros & Developers. It's quick & easy.

int main(int argc, char* argv[]) & int main(int argc, char** argv)

P: n/a
Hi,

I have a question. I created a simple executable program using Visual C++
from Visual Studio 6.0

This program is called from a script that passes in one argument.

Now, my question is:

1. When I use int main(int argc, char* argv[]) declaration, the argv usually
contains the data and some garbage at the end.

For example: a script calls this executable and passes in data =this-is-me
When it executes this C++ program, the argv contains =this-is-me@#

Where did the @# come from? and Why?

2. When I use main(int argc, char** argv) declaration, the argv is exactly
what the script passes it.

For example: a script calls this executable and passes in data =this-is-me
When it executes the C++ program, the argv contains exactly =this-is-me

So, what is the difference between these two declarations? Why does the
first one contains garbage characters?

Please help me to understand. I am fairly new at Visual C++.

Many Thanks
Jan 5 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
On Thu, 4 Jan 2007 21:22:01 -0800, Vin <Vi*@discussions.microsoft.com>
wrote:
>Hi,

I have a question. I created a simple executable program using Visual C++
from Visual Studio 6.0

This program is called from a script that passes in one argument.

Now, my question is:

1. When I use int main(int argc, char* argv[]) declaration, the argv usually
contains the data and some garbage at the end.

For example: a script calls this executable and passes in data =this-is-me
When it executes this C++ program, the argv contains =this-is-me@#

Where did the @# come from? and Why?

2. When I use main(int argc, char** argv) declaration, the argv is exactly
what the script passes it.
I don't understand how that can be. For function parameter declarations,
and only function parameter declarations, char** and char*[] mean the same
thing, pointer-to-pointer to char. Similarly, and again, in only this
context, char* and char[] mean the same thing, which is pointer to char.
>For example: a script calls this executable and passes in data =this-is-me
When it executes the C++ program, the argv contains exactly =this-is-me

So, what is the difference between these two declarations? Why does the
first one contains garbage characters?
There is no difference. So there necessarily is some other difference,
which could be a compiler bug, though I cannot recall ever hearing of a
compiler bug such as this. How are you determining what the strings
contain?
>Please help me to understand. I am fairly new at Visual C++.
If you are a newcomer to C++, don't feel bad, because arrays and pointers
are not the same thing at all, even though the syntax sometimes disagrees,
all in the interest of helping you declare things the way the language
designer thought you'd use them. The C FAQ has a lot of good information on
the subject:

6. Arrays and Pointers
http://c-faq.com/aryptr/index.html

--
Doug Harrison
Visual C++ MVP
Jan 5 '07 #2

P: n/a
How do you access the arguments in both cases? Can you show some code?
The correct way with char argv[] is:

int main(int argc, char argv[])
{
if (argc>1)
printf("1st program argument=%s\n", argv[1]);
else
printf("Program %s is running without arguments\n", argv[0]);
}

--
Cholo Lennon
Bs.As.
ARG
"Vin" <Vi*@discussions.microsoft.comescribió en el mensaje
news:80**********************************@microsof t.com...
Hi,

I have a question. I created a simple executable program using Visual C++
from Visual Studio 6.0

This program is called from a script that passes in one argument.

Now, my question is:

1. When I use int main(int argc, char* argv[]) declaration, the argv usually
contains the data and some garbage at the end.

For example: a script calls this executable and passes in data =this-is-me
When it executes this C++ program, the argv contains =this-is-me@#

Where did the @# come from? and Why?

2. When I use main(int argc, char** argv) declaration, the argv is exactly
what the script passes it.

For example: a script calls this executable and passes in data =this-is-me
When it executes the C++ program, the argv contains exactly =this-is-me

So, what is the difference between these two declarations? Why does the
first one contains garbage characters?

Please help me to understand. I am fairly new at Visual C++.

Many Thanks

Jan 5 '07 #3

P: n/a
Thanks for all responses. I access the arguments for both cases using
argv[1]...argv[n]
Hi,
That could be the problem. indexing in arrays is 0 based. meaning the first
element has index 0, and the last element has index n-1.
if n is the size of your array, indexing should be done
argv[0]...argv[n-1]

--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Jan 5 '07 #4

P: n/a
Vin wrote:
Thanks for all responses. I access the arguments for both cases using
argv[1]...argv[n]

But what's up with the @# and where did it come from?
If you address an item outside of the array's memory space, such things
are expected to happen. Nobody knows where it's coming from, that's just
the content of your memory -- garbage, or the content of other objects,
perhaps leftover by the operating system or the debugger. You have no
control over that. Once you address an invalid pointer, the consequences
are undefined and somewhat random.
It will only show up for char* argv[] and not for char** argv
As others have already stated it, there's no difference between those
two types when they are used in function arguments.

If you don't believe it, cut and paste these 2 definitions:
void f(char* argv[]) { }
void f(char** argv) { }

You'll get a compiler error, something like "body has already been
defined for 'f(char**)'". They violate the One Definition Rule, because
they're identical.
for char* argv[]: Another weird thing is that at times it will have this @#
and at other times it doesn't.
See, this just proves the random nature of this behavior. It doesn't
depend on whether the type is char*[] or char**, but on circumstances
beyond your control. Due to a programming error, you're exploiting
undefined behavior. I have no question in my mind that when you use that
array properly, it will return the correct value.

Tom
Jan 5 '07 #5

P: n/a
On Fri, 5 Jan 2007 00:15:00 -0800, Vin <Vi*@discussions.microsoft.com>
wrote:
>Hi,

Thanks for all responses. I access the arguments for both cases using
argv[1]...argv[n]

But what's up with the @# and where did it come from?

It will only show up for char* argv[] and not for char** argv

for char* argv[]: Another weird thing is that at times it will have this @#
and at other times it doesn't. Also if I execute the program on another
computer it never show up all.

Any ideas?
If you're using argv[n] for n argc, the result is undefined, which means
anything is possible. You can compile with /FAs and compare the assembly
code generated by the compiler, but if the only difference is char** vs.
char*[], I'd expect it to be the same. How are you determining what the
strings contain? Show the code.

--
Doug Harrison
Visual C++ MVP
Jan 5 '07 #6

P: n/a
Thanks for all responses. I access the arguments for both cases using
argv[1]...argv[n]

But what's up with the @# and where did it come from?
If you go beyond the boundaries of the array, you get undefined values.
I.e. argv[n] returns something, but whatever it is is not subject to logical
behavior. You just get whatever value happens to be after argv[n-1]

That value is then interprested as a char pointer. That pointer can point
anywhere, since is is not a real pointer.
When you try to use that pointer to read a string, the string function will
start at that pointer, and search until it finds a 0 that indicates the end
of the string.

If you are lucky, it will find a 0 and use a bogus string.
if you are unlucky, it will continue searching until it hits an inaccessible
addres, at which time you will get an access violation.

since this is undefined behavior, you cannot compare what happens on 2
different computers, or 2 different runs of the application.
Your result depends on whatever happens to be in argv[n] when you read it.

--
Kind regards,
Bruno.
br**********************@hotmail.com
Remove only "_nos_pam"

Jan 8 '07 #7

P: n/a
In article <E3**********************************@microsoft.co m>,
=?Utf-8?B?Vmlu?= <Vi*@discussions.microsoft.comwrote:
>Thanks for all responses. I access the arguments for both cases using
argv[1]...argv[n]
C/C++ count arrays from 0, so that the array boundaries should be
argv[0] .. argv[n-1]. Also, C/C++ tends to treat array sizes as merely
suggestions, not hard limits. You can invite a lot of security
problems in your programs if you don't program defensively. C/C++
tends to give you all the tools you need to shoot yourself in the
foot-- and offers you a bigger bullet. This gives them a lot of power,
but if you can't handle that power properly, you might want to
consider another language.

Nathan Mates
--
<*Nathan Mates - personal webpage http://www.visi.com/~nathan/
# Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein
Jan 8 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.