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

dauxcl2d  于 2023-10-16  发布在  其他
关注(0)|答案(9)|浏览(164)

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

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

svujldwt1#

我假设你使用的是C99编译器(带有support for dynamically sized arrays)。代码中的问题是,当编译器看到你的变量声明时,它无法知道数组中有多少个元素(我还假设,从编译器错误中,length不是编译时常量)。
您必须手动初始化该数组:

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

xa9qqrwz2#

你收到这个错误,因为在C语言中,你不允许使用可变长度数组的初始化器。你得到的错误信息基本上说明了一切。

6.7.8分

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

ruyhziif

ruyhziif3#

这会导致错误:

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";
mgdq6dx1

mgdq6dx14#

在声明数组之后

int boardAux[length][length];

将初始值赋值为零的最简单方法是使用for循环,即使它可能有点长

int i, j;
for (i = 0; i<length; i++)
{
    for (j = 0; j<length; j++)
        boardAux[i][j] = 0;
}
ef1yzkbh

ef1yzkbh5#

可变长度数组是编译器在编译时不知道其长度的数组。length是一个变量。我得出这个结论,因为如果length是一个例如。预处理器宏定义为一个文字整数你的初始化将工作。1989年的第一个C语言标准不允许可变长度数组,它们是在1999年添加的。C标准仍然不允许用像你这样的表达式来初始化这些(尽管有人可能会认为它可以或应该允许它)。
初始化变量数组的最佳方法如下:

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

memset是一个非常快速的标准库函数,用于初始化内存(在上面的例子中为0)。sizeof(boardAux)返回boardAux占用的字节数。sizeof始终可用,但memset需要#include <string.h>。是的-sizeof允许可变大小的对象作为参数。
注意,如果你有一个普通的数组(不是可变长度的),并且只想将内存初始化为零,你永远不需要嵌套的括号,你可以简单地像这样初始化它:

struct whatEver name[13][25] = {0};
wydwbb8l

wydwbb8l6#

数组没有初始化指定的内存anf抛出错误variable sized array may not be initialised我更喜欢通常的初始化方式,

for (i = 0; i < bins; i++)
        arr[i] = 0;
s5a0g9ez

s5a0g9ez7#

这个问题已经得到了回答,但我想指出另一个解决方案,它是快速的,如果长度不打算在运行时改变,它也可以工作。在main()之前使用宏#define来定义长度,在main()中你的初始化将工作:

#define length 10

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

宏在实际编译之前运行,长度将是编译时常量(正如大卫罗德里格斯在他的回答中所提到的)。在编译之前,它实际上会将length替换为10。

ovfsdjhp

ovfsdjhp8#

在C23之前,不允许初始化可变长度数组

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

因此,您必须在之后手动初始化它。零初始化通常使用memset来完成。
自C23以来,可变长度数组的初始化规则已经改变:
6.7.10.
1.要初始化的实体的类型应该是未知大小的数组或完整的对象类型。一个可变长度数组类型的实体不能被初始化**,除非是一个空的初始化器**。一个未知大小的数组不能用空的初始化器初始化。
这意味着,从C23开始,你可以初始化一个VLA,但只能用一个空的初始化器来零初始化它。

int boardAux[length][length] = {}; // OK since C23
// memset( boardAux, 0, length*length*sizeof(int) ); // No longer needed
z3yyvxxp

z3yyvxxp9#

简单地声明长度是一个缺点,如果不是,那么你应该动态分配内存

相关问题