【问题标题】:Array of unknown bound usage in C programmingC 编程中未知边界用法的数组
【发布时间】:2017-05-31 09:29:44
【问题描述】:

当我多次运行时,以下代码的输出未定义。我想知道为什么输出是未定义的,以及当我尝试将值分配给一个未知边界的数组时会产生什么影响。

#include <stdio.h>

int main()
{
  int a[]= {};
  int num_of_elements;
  int count = 0;

  printf("Enter the number of elements:\n");
  scanf("%d",&num_of_elements);

  printf("Enter the numbers:\n");
  for(count=0; count<num_of_elements; ++count)
  {
    scanf("%d", &a[count]);
  }
  printf("\n");

  for(count=0; count<num_of_elements; count++)
  {
    printf("%d,   ", a[count]);
  }
  printf("\n");

  return 0;
}

在不同时间运行时的输出:

Enter the number of elements:
2

Enter the numbers:
1 2

0,   0,

Enter the number of elements:
3

Enter the numbers:
1 2 3

0,   0,   2,

Enter the number of elements:
4

Enter the numbers:
1 2 3 4

0,   0,   2,   3,
Segmentation fault

Enter the number of elements:
5

Enter the numbers:
1 2 3 4 5

0,   0,   2,   3,   4,
Segmentation fault

【问题讨论】:

  • int a[]= {}; 没有用 - 您必须在 知道它的大小之后定义数组。
  • 贴出的代码无法编译!它会导致编译器输出两条消息:1)5:12: warning: ISO C forbids empty initializer braces [-Wpedantic] 和 2)5:7: error: zero or negative size array 'a' 编译时始终启用警告。然后修复这些警告。 (对于gcc,至少使用:-Wall -Wextra -pedantic

标签: c segmentation-fault undefined-behavior


【解决方案1】:

作为第一个提示,当您尝试使用 gcc 使用 -pedantic 编译它时,它将拒绝编译:

$ gcc -std=c11 -Wall -Wextra -pedantic -ocrap.exe crap.c
crap.c: In function 'main':
crap.c:5:12: warning: ISO C forbids empty initializer braces [-Wpedantic]
   int a[]= {};
            ^
crap.c:5:7: error: zero or negative size array 'a'
   int a[]= {};
       ^

事实上,这样一个变量的大小是0,所以你不能在其中存储任何东西

它仍然是一种有效的语法并有其用途,例如作为结构的“灵活数组成员”:

struct foo
{
    int bar;
    int baz[];
};

[...]

struct foo *myfoo = malloc(sizeof(struct foo) + 5 * sizeof(int));
// myfoo->baz can now hold 5 integers

【讨论】:

    【解决方案2】:

    我想知道为什么输出是未定义的,以及当我尝试将值分配给一个未知边界的数组时会产生什么影响

    变量a的大小将是0,因为此时num_of_elements还没有被scanf'ed,所以你不能在里面存储任何东西。

    解决方案是在从用户那里读取数组的大小后声明数组。这意味着:

    #include <stdio.h>
    
    int main()
    {
        int num_of_elements;
        int count = 0;
    
        printf("Enter the number of elements:\n");
        scanf("%d", &num_of_elements);
    
        //define here your array
        int a[num_of_elements];
    
        ...
    
        return 0;
    }
    

    【讨论】:

    • 仅当__STDC_NO_VLA__定义为宏标识符。
    • @DeiDei OP 没有在他的程序中提到这样的宏定义......这就是为什么我没有提到这个。
    • 嗨 Marievi 和其他人...感谢您的意见。现在很清楚,感谢您介绍 C11 标准,这给了我一些见解
    • 编译这个答案会导致:1)12:5: error: variable sized objct may not be initialized. 2)12:30: warning: ISO C forbids empty initializer braces [-Wpedantic]
    猜你喜欢
    • 2021-08-27
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多