C编译错误:“变量大小的对象可能未初始化”


97

为什么我收到以下代码错误“变量大小的对象可能未初始化”?

int boardAux[length][length] = {{0}};

正如David Rodriguez的出色回答所指出的那样:如果length是一个变量,则需要memset,但是如果length是一个编译时常量,则该语句可以正常编译。
凯西

ffwd到2020年–enum {length = 0xF } ; int boardAux[length][length] = {0};
厨师角斗士

Answers:


121

我假设您正在使用C99编译器(支持动态大小的数组)。您的代码中的问题是,当编译器看到您的变量声明时,它无法知道数组中有多少个元素(我在这里也假设来自编译器的错误,length它不是编译时间常数)。

您必须手动初始化该数组:

int boardAux[length][length];
memset( boardAux, 0, length*length*sizeof(int) );

我也可以将malloc用于此目的,第二个问题是什么,我是在Pavel回复后写的
helloWorld 2010年

@helloWorld:使用堆栈分配的数组,可以正常printf( "%d", boardAux[1][2] )编译。编译器知道大小,并且知道第(1,2)个元素在内存中的哪个位置。如果使用动态分配的数组是一维的,你必须自己进行数学运算:printf("%d", boardAux[ 1*length + 2 ])
大卫·罗德里格斯- dribeas

@AndreyT:感谢您指出memset调出的错误。我刚刚更正了它。
DavidRodríguez-dribeas 2010年

我为什么会在C99编译器这个错误,当我设置的lengthstatic?在C ++ 14中,它可以正常工作。
Muhamed Cicak

25

收到此错误的原因是,在C语言中,不允许将初始化程序与可变长度数组一起使用。您收到的错误消息基本上说明了一切。

6.7.8初始化

...

3要初始化的实体的类型应为未知大小的数组或不是可变长度数组类型的对象类型。


您在哪里找到的,可以给我链接吗?
helloWorld 2010年

1
@helloWorld:这是来自语言标准(C99)。您可以在此处获取
AnT 2010年

5
如果您仅提供非正式的说明,有些主题将永远使您不相信。可变长度数组是这些主题之一。+1用于引用标准。
Pascal Cuoq 2010年

15

这给出了错误:

int len;
scanf("%d",&len);
char str[len]="";

这也会产生错误:

int len=5;
char str[len]="";

但这很好用:

int len=5;
char str[len]; //so the problem lies with assignment not declaration

您需要通过以下方式实现价值:

str[0]='a';
str[1]='b'; //like that; and not like str="ab";


1

该问题已得到解答,但我想指出另一种解决方案,该解决方案是快速的,并且如果不希望在运行时更改长度,则可以使用。在main()之前使用#define宏定义长度,并在main()中进行初始化:

#define length 10

int main()
{
    int boardAux[length][length] = {{0}};
}

在实际编译之前运行宏,并且长度将是编译时常量(如DavidRodríguez在其回答中所提及)。实际上,它将在编译之前用10代替长度。


0

只需声明length为一个弊端,如果不是,那么您应该动态分配内存


2
我认为您需要查看const的含义!
霍尔格

@霍尔格:你确定吗?如果保存长度的变量(不是数组本身,而是数组长度)是一个常数,则编译器知道用于初始化数组的长度。例如,“ int length = 5; int array [length];” 给出错误,但“ const int length = 5; int array [length];” 编译就好了。
Casey

0
int size=5;
int ar[size ]={O};

/* This  operation gives an error -  
variable sized array may not be 
initialised.  Then just try this. 
*/
int size=5,i;
int ar[size];
for(i=0;i<size;i++)
{
    ar[i]=0;
}

1
欢迎使用Stack Overflow!请阅读有关如何写一个好的答案的指南:stackoverflow.com/help/how-to-answer您当前的答案似乎含糊不清,没有任何解释
gybandi

-5

对于C ++,像这样分别声明和初始化。

int a[n][m] ;
a[n][m]= {0};

1
不是C ++问题
Cacahuete Frito

上面仅初始化A [n] [m],而不初始化整个数组。int a [n] [m]; memset(a,0,(n m sizeof(int)); //清除数组的内存大多数编译器都允许这样做:int a [n] [m] = {0}; //将所有成员初始化为0
Chris Reid

-9

你做不到。C编译器无法在堆栈上执行如此复杂的操作。

您必须使用堆和动态分配。

您真正需要做的是:

  • 计算所需内存的大小(n m sizeof(element))
  • 调用malloc(size)分配内存
  • 创建访问器:int * access(ptr,x,y,rowSize){return ptr + y * rowSize + x; }

使用* access(boardAux,x,y,size)= 42与矩阵进行交互。


还有一个问题,为什么我收到错误使用未指定范围的数组的错误信息?printf(“%d”,board [i] [j]);
helloWorld

10
-1 C99允许在堆栈中作为用户代码动态分配(不包括初始化)。无需执行动态分配。
DavidRodríguez-dribeas 2010年

@helloWorld,因为必须知道数组的尺寸。
帕维尔·拉兹维洛夫斯基
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.