我发现两种方式传递的命令行参数字阵列:

int main (int argc, char **argv)
{
  const char *s1 = argv[0];
  char s2[256];
  strcpy(s2, argv[0]);

  printf("s1: %s\ns2: %s\n\n", s1, s2);
}

编制与IBM xlc编译器在AIX系统的回报

[MyPrompt]>./a.出来

s1:./a.出来

s2:./a.出来

其执行情况(s1或s2)是否正确?s1是不错的,因为argv[0]可以是任何长度。s2中要求的长度argv[0] < 256符。

我不明白为什么s1应工作。我 想想 右手边的s1应要求在编制时间,但我 想想 它的产生,在运行时间。

有帮助吗?

解决方案

s1起作用的原因是因为argv [0] 的类型是指针。您只需分配地址(而不是实际值),这是安全的。您没有进行任何类型的分配或演员。

我通常更喜欢第一个选项,因为您应该只读取参数变量。

其他提示

如果您不想更改字符串,那么s1将起作用。

如果您想更改字符串,则可以复制它。如果你的系统支持它,你应该使用更安全的strnlen()和strncpy()。

  

我认为s1的右侧   应该在编译时需要,   但我认为它是由...产生的   运行时间。

不,每次遇到语句都需要它。例如:

void f() {
   int x = 1;
   ...
}

每次调用函数时,整数x都将初始化为1,而不是在编译时。

s2具有令人愉快的财产是容易受到缓冲区溢出。

我已经看到改变人们的价值argv[0].在某些情况下,(在一些操作系统)改变argv[0]将会使程序出现在ps为什么你改变它。

如果您只是想引用参数而不对其进行任何更改,那么 s1 是正确的。

如果您需要以任何方式修改参数,那么您需要像 s2 示例中那样复制它,但在 s2 示例中,您需要明确检查查看长度是否比您要复制到的缓冲区长。例如,如果您正在使用像filename.jpg这样的参数作为输入并保存filename.gif作为输出,那么您需要复制该参数,因为您将把扩展名从.jpg更改为.gif

我会选择s1,特别是对于argv [n],其中n <!> gt;像s2这样的东西打开你的经典缓冲区溢出攻击。基本上,用户可以格式化长度超过256个字符的参数并覆盖堆栈上的信息,以便它们可以运行他们想要的任何代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top