C编程中未知绑定用法的数组

时间:2017-05-31 09:29:44

标签: c segmentation-fault undefined-behavior

当我多次运行时,下面代码的输出是未定义的。我想知道为什么输出是未定义的,当我尝试将值赋给未知边界的数组时会有什么含义。

#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

2 个答案:

答案 0 :(得分:1)

  

我想知道为什么输出未定义,当我尝试将值赋给未知绑定数组时会有什么含义

变量a的大小为0,因为此时num_of_elements尚未scanf,因此您无法在其中存储任何内容。

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

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

答案 1 :(得分: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