Question

I write a test which print the content of argv[0]--the address of main function's parameter as followed:

printf("%p\n",argv[0]);

I compiled the program with Visual Studio 2008 on Windows 7.

Then I executed the program 1000 times which output the results to a file. As a result, the address of argv[0] changes, however, some addresses are the same and repeat about 10 times.

Why the address of main function's parameter changes each time?

Was it helpful?

Solution

Interesting question, I see very few or no reasons for non-determinism of that in program's own address space. But I will tell you what I do know.

First, argv is allocated, created and initialized not by windows but by stdc runtime. Which, in turn, raises another question - does lpCmdLine parameter of winmain also change? There're several other variables allocated on the same heap, probably environment vars are also copied. One of them must have size depending on the instance of execution.

Anyway, why blackbox pondering? Where's your disassembler, soldier?

OTHER TIPS

argc and argv should be placed onto the stack before the begin of the main routine of the binary executable. Actually I think that argv is dynamically allocated somewhere inside the heap and then the pointer is placed onto the stack.

This means that the heap allocator is the one that cares about where the data is allocated and this is why it changes everytime (it depends on the policy).. your program will ask to the OS to allocate the space for the arguments (think about passing through malloc) so there can be internal choices made according to something (like the ASLR they were talking about)

First of all, here's what the language standard (n1256) has to say:

5.1.2.2.1 Program startup
...
2 If they are declared, the parameters to the main function shall obey the following constraints:

  • The value of argc shall be nonnegative.

  • argv[argc] shall be a null pointer.

  • If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.

  • If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters.

  • The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

The last bullet is the most interesting with respect to where the string arguments passed to main are stored. They must be modifiable and they must have static extent, which places some limits on where they reside in memory. There's no requirement on the part of the language definition that they reside in the same location every time the program is run, though.

I've done a cursory search through MSDN to see if they say anything explicit, but haven't found anything yet. It probably comes down to ASLR as mentioned in the comments to the OP.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top