为什么main函数的参数地址每次都会改变?
我编写了一个测试,打印 argv[0] 的内容——主函数参数的地址,如下所示:
printf("%p\n",argv[0]);
我在 Windows 7 上使用 Visual Studio 2008 编译了程序
。然后我执行了程序 1000 次,将结果输出到文件中。结果,argv[0]的地址发生了变化,但有些地址是相同的,并且重复了大约10次。
为什么main函数的参数地址每次都会变化?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有趣的问题,我认为程序自己的地址空间中的非确定性的原因很少或根本没有。但我会告诉你我所知道的。
首先,argv不是由windows而是由stdc运行时分配、创建和初始化的。这反过来又提出了另一个问题 - winmain 的 lpCmdLine 参数也会改变吗?在同一个堆上分配了几个其他变量,可能环境变量也被复制。其中之一的大小必须取决于执行实例。
无论如何,为什么要进行黑盒思考呢?你的反汇编器在哪里,士兵?
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?
argc
和argv
应在二进制可执行文件的主例程开始之前放入堆栈。实际上我认为 argv 是在堆内的某个位置动态分配的,然后指针被放置到堆栈上。这意味着堆分配器是关心数据分配位置的分配器,这就是它每次都会更改的原因(这取决于策略)..您的程序将要求操作系统为参数分配空间(考虑一下通过
malloc
),因此可以根据某些内容做出内部选择(例如他们正在谈论的 ASLR)argc
andargv
should be placed onto the stack before the begin of the main routine of the binary executable. Actually I think thatargv
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)首先,这是语言标准(n1256)必须说:
最后一个项目符号是最有趣的,因为传递给
main
的字符串参数的存储位置。它们必须是可修改的,并且必须具有静态范围,这对它们在内存中的驻留位置施加了一些限制。不过,语言定义部分并不要求每次程序运行时它们都驻留在同一位置。我粗略地搜索了 MSDN,看看他们是否说了任何明确的内容,但还没有找到任何内容。正如OP评论中提到的那样,它可能归结为ASLR。
First of all, here's what the language standard (n1256) has to say:
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.