【问题标题】:How do I handle argv character array assignments?如何处理 argv 字符数组分配?
【发布时间】:2009-08-01 03:14:10
【问题描述】:

我发现了两种将命令行参数传递到字符数组的方法:

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);
}

在 AIX 系统上使用 IBM xlc 编译器编译返回

[我的提示]> ./a.out

s1: ./a.out

s2: ./a.out

哪个实现(s1 或 s2)是正确的? s1 很好,因为 argv[0] 可以是任意长度。 s2 要求 argv[0] 的长度

我不明白 s1 如何/为什么应该工作。我认为 s1 的右侧应该在编译时需要,但我认为它是在运行时生成的。

【问题讨论】:

    标签: c argv


    【解决方案1】:

    s1 起作用的原因是因为 argv[0] 的类型是一个指针。您只是分配地址(不是实际值),这是安全的。您没有执行任何类型的分配或强制转换。

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

    【讨论】:

    • 如果是这样的话,我是不是应该把int main的参数改成(const int argc, const char **argv)?
    • 你不能的唯一原因是可移植性:可能有编译器不接受它。
    • const 是 C 语言的新增功能,并且由于 main() 是在 C 的古老童年时代定义的,因此它没有 const 修饰。但是 char* 是可以转换为 const char* 的,所以不用担心不一致。
    • j0rd4n:这不太对。您始终可以将指向 const 的指针指向指向非 const 的指针。反过来是不合法的。
    • main 的签名来自时间的迷雾深处,不能乱来。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我认为 s1 的右手边 应该在编译时需要, 但我认为它是在 运行时。

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

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

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

      【讨论】:

        【解决方案4】:

        s2 具有易受缓​​冲区溢出影响的令人愉快的特性。

        我见过人们改变 argv[0] 的值。在某些情况下,(在某些操作系统上)更改 argv[0] 将使程序在 ps 中显示为您将其更改为的任何内容。

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              猜你喜欢
              • 2015-04-25
              • 2015-01-21
              • 2016-05-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-01-06
              • 1970-01-01
              相关资源
              最近更新 更多