【问题标题】:Something mysterious happening? [duplicate]发生了什么神秘的事情? [复制]
【发布时间】:2017-04-24 09:13:43
【问题描述】:

我有一个与此代码相关的问题。

 #include <stdio.h>
 void main() 
 {
        char array[0];
        scanf("%s", array);
        printf("%s", array);
        return;
 } 

当我在输入字段中输入数据时,它会存储在数组中并获得输出,但它的大小是 0。

另一件事发生的是,当我输入假设 'a' 12 次然后以某种方式控制到达 scanf() 以获取输入,然后再次输入 'a' 12 次控制再次到达 scanf() 并且这样直到我输入少于 12 个字符。

如果输入超过 12 个字符,程序就会崩溃。

为什么会这样?

【问题讨论】:

  • 未定义的行为。
  • 您的编译器应该会生成一条错误消息,0 的大小是违反约束的。
  • @Olaf - 不一定 - GCC 提供零长度数组作为 compiler-specific 扩展......但是,写入这样的数组仍然是未定义的行为(除非有是从正确分配的更大内存中投射出来的)。
  • @Aconcagua:问题没有说明它是哪个编译器,因此代码确实调用了UB。即使有这个多余的扩展,代码也会调用 UB 来解除对无效指针地址的引用。
  • 也许你的意思是int main(void)...

标签: c arrays


【解决方案1】:

类似的声明

 char array[0];

根据 ISO C 是无效代码。这是纯粹的约束违规。大小必须大于 0。

引用C11,第 §6.7.6.2 章(强调我的

除了可选的类型限定符和关键字static[] 可以分隔 表达式或*。如果它们分隔了一个表达式(它指定了一个数组的大小),则 表达式应具有整数类型。 如果表达式是一个常量表达式,它应该 具有大于零的值。 [...]

也就是说,

  • void main() 不是托管环境的一致签名。它至少需要为int main(void) 才能符合标准。

  • 在使用scanf() 和家人时,总是

    • 通过提供最大字段宽度来限制输入的长度,例如

      char input [10] = {0};
      scanf("%9s", input);
      
    • 检查返回值,确保调用成功。

【讨论】:

  • @AmanWarudkar 这是什么?随机实验?阅读基础知识并事先了解您要达到的目标。无论如何,仅仅因为您可以输入任何内容,并不能使其成为有效代码。
  • 好的,然后将数组的大小设置为 1,上图继续输入字符 13 次。
  • @AmanWarudkar 您需要提供足够的缓冲区来保存要扫描的输入,例如。 G。 char array[32];。此外,您绝对应阻止 scanf 写入此缓冲区之外:scanf("%31s", array);.
  • @AmanWarudkar 读到了undefined behavior,你的代码中有一个。
  • @AmanWarudkar 更糟糕的是......不要那样做。通过仔细学习和实践来学习 C,而不是通过随机实验。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 2020-07-27
相关资源
最近更新 更多