【问题标题】:argc / argv affects null byte in arrays?argc / argv 影响数组中的空字节?
【发布时间】:2016-01-12 08:19:15
【问题描述】:

为什么会这样:

#include <stdio.h>

int main(int argc, char *argv[])
{
     char array[3] = {'1', '2', '3'};
     printf("%s\n", array);

     return 0;
}

按预期产生1238À§Wˇ(“123”+一些随机字符),而相同的代码具有:

int main(void)

而不是argcargv 生成:123(尽管空字节没有空间)。

arrayvoid 中的空字节空间不足似乎无关紧要?

【问题讨论】:

  • 一种未定义的行为可能与另一种不同:)。顺便说一句,char array[3] = { '1', '2', '3', '4' }; 真的可以编译吗?
  • 您的意思是char array[3] = {'1', '2', '3'};?您甚至没有为'4' 分配足够的空间。那是违反约束的;编译器可以将其视为致命错误。 (不幸的是,gcc 默认只发出警告。)
  • 所以你尝试将四个字节放入一个 3 字节的数组中,不要费心用 NUL 终止它,然后想知道为什么它打印为字符串时会打印垃圾?这是未定义的行为。
  • 使用main(void) 似乎可以解决问题,但实际上并非如此。使用另一个编译器、另一台机器、另一个目标架构,可能会导致“预期”问题。重要的是,您不会得出结论认为不使用 main 的参数可以解决问题,因为这是错误的。如果你想在 ideone.com 上尝试,你会发现在这两种情况下它实际上都没有输出任何东西,甚至 123 也没有(尽管我不得不承认我不明白为什么)

标签: c arrays argv argc nul


【解决方案1】:

您没有提供字符串结尾 (EOS) 零字节,因此 printf 会一直运行,直到它 [恰好] 找到一个(即垃圾字符)。

以下任何一种都可以:

char array[4] = { '1', '2', '3', '\0' };
char array[4] = { '1', '2', '3' };
char array[4] = "123";
char array[] = { '1', '2', '3', '\0' };
char array[] = "123";
char *array = "123";

【讨论】:

    【解决方案2】:

    当你这样做时:

    char array[3] = {'1', '2', '3'};
    printf("%s\n", array);
    

    您正在调用未定义的行为,因为字符数组不是 NUL 终止的。你可能会得到“123”,或者什么都没有,或者类似的想法,或者它可能会根据任意条件而有所不同。

    在您的具体情况下,只是一个有根据的猜测,在局部变量 array 之后,它可能是函数参数的内存,而这些恰好是 argcargv。根据main 的实际参数,甚至传递给程序的运行时值,这些内存位置上的字节会有所不同。有时它们必须在适当的位置有一个 NUL 字节并影响程序的输出。

    无论如何,我的建议是不要过度考虑 UB 的情况。最好将它们视为未定义

    【讨论】:

      猜你喜欢
      • 2011-04-15
      • 1970-01-01
      • 2013-09-08
      • 1970-01-01
      • 2015-09-01
      • 1970-01-01
      • 2014-01-10
      • 2017-08-10
      • 2020-05-24
      相关资源
      最近更新 更多