2

我写了一个测试,打印 argv[0] 的内容——主函数参数的地址如下:

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

我在 Windows 7 上使用 Visual Studio 2008 编译了该程序。

然后我执行程序 1000 次,将结果输出到文件中。结果,argv[0] 的地址发生了变化,但是,有些地址是相同的,并且重复了大约 10 次。

为什么main函数的参数地址每次都变?

4

3 回答 3

2

argc并且argv应该在二进制可执行文件的主程序开始之前放入堆栈。实际上我认为这argv是在堆内的某个地方动态分配的,然后将指针放在堆栈上。

这意味着堆分配器是关心数据分配位置的那个,这就是为什么它每次都会改变(这取决于策略)..您的程序将要求操作系统为参数分配空间(想想通过malloc),因此可以根据某些东西(比如他们正在谈论的 ASLR)做出内部选择

于 2010-11-17T14:51:13.087 回答
1

有趣的问题,我认为程序自己的地址空间中的不确定性很少或根本没有原因。但我会告诉你我所知道的。

首先,argv 不是由 windows 而是由 stdc 运行时分配、创建和初始化的。这反过来又引发了另一个问题——winmain 的 lpCmdLine 参数是否也会改变?在同一个堆上分配了其他几个变量,可能还复制了环境变量。其中之一必须具有取决于执行实例的大小。

无论如何,为什么要黑盒思考?士兵,你的拆解机在哪里?

于 2010-11-17T14:57:50.633 回答
0

首先,这是语言标准(n1256)必须说的:

5.1.2.2.1 程序启动
...
2 如果声明它们,主函数的参数应遵守以下约束:

  • 的值argc应为非负数。

  • argv[argc]应为空指针。

  • 如果 的值argc大于零,则argv[0]通过 argv[argc-1]inclusive 的数组成员应包含指向字符串的指针,这些指针在程序启动之前由宿主环境赋予实现定义的值。目的是从托管环境中的其他地方向程序提供在程序启动之前确定的信息。如果主机环境不能提供大写和小写字母的字符串,则实现应确保以小写形式接收字符串。

  • 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.

于 2010-11-17T16:05:52.367 回答