【问题标题】:C compile error: "Variable-sized object may not be initialized"C 编译错误:“可变大小的对象可能未初始化”
【发布时间】:2011-03-06 04:54:29
【问题描述】:

为什么我会收到错误“可变大小的对象可能未初始化”的错误信息?

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

【问题讨论】:

  • 正如 David Rodriguez 在出色回答中指出的那样:如果长度是变量,则需要 memset,但如果长度是编译时常量,则该语句编译得很好。
  • 到 2020 年——enum {length = 0xF } ; int boardAux[length][length] = {0};
  • 将其设为const int 为我解决了这个问题。
  • @MoteZart 做到了吗?给定const int length = 1; int boardAux[length][length] = {{0}}; boardAux 是一个可变长度数组,而length 不是 一个常量表达式。请记住,const 仅表示只读;这并不意味着“恒定”。 (length 是 C++ 中的常量表达式,不支持变长数组。)

标签: c compiler-errors initializer-list variable-length-array


【解决方案1】:

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

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

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

【讨论】:

  • 我也可以使用malloc,第二个问题呢,我是在Pavel回复后写的
  • @helloWorld:使用堆栈分配的数组,printf( "%d", boardAux[1][2] ) 编译得很好。编译器知道大小并且知道第 (1,2) 个元素在内存中的位置。如果您使用动态分配,则数组是一维的,您必须自己执行数学运算:printf("%d", boardAux[ 1*length + 2 ])
  • @AndreyT:感谢您指出memset 呼叫中的错误。我刚刚更正了。
  • 当我将length 设置为static 时,为什么在C99 编译器中会出现此错误?在 C++14 中它工作正常。
  • 我想知道malloc不需要的原因。
【解决方案2】:

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

6.7.8 初始化

...

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

【讨论】:

  • 你在哪里找到这个的,你能给我一个链接吗?
  • @helloWorld:这是来自语言标准 (C99)。您可以在此处获取带有 TC3 更新的“工作”副本open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
  • 如果你只提供非正式的解释,有些主题总会有人不相信你。可变长度数组是这些主题之一。 +1 引用标准。
  • @AnT 我在 C++ 中运行代码,它编译得很好,所以可变大小数组的初始化在 C++ 中有效?
  • @Abhishek Mane:不。C++ 根本没有可变大小的数组。
【解决方案3】:

这给出了错误:

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

【讨论】:

    【解决方案4】:

    只需将长度声明为一个缺点,如果不是,那么您应该动态分配内存

    【讨论】:

    • 我觉得你需要查一下 const 是什么意思!
    • @Holger:你确定吗?如果保存长度的变量(不是数组本身,而是数组长度)是一个常数,那么编译器就知道用于初始化数组的长度。例如,“int length=5;int array[length];”给出错误但“const int length=5; int array[length];”编译就好了。
    • @Casey: 但const int lenght=5; int array[length][length] = {{0}}; 不会。
    【解决方案5】:

    声明数组后

    int boardAux[length][length];
    

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

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

    【讨论】:

    • memset 更简单、更快捷。
    • 我觉得这样更简单自然。 @alx
    【解决方案6】:

    问题已经得到解答,但我想指出另一种解决方案,如果不打算在运行时更改长度,则该解决方案速度快且有效。在 main() 之前使用宏 #define 来定义长度,在 main() 中你的初始化将起作用:

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

    宏在实际编译之前运行,长度将是编译时常量(正如 David Rodríguez 在他的回答中所提到的)。它实际上会在编译之前将长度替换为 10。

    【讨论】:

    • {0}{{0}} 之间有什么真正的区别吗?
    • 这实际上并没有创建一个可变大小的对象。
    【解决方案7】:
    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;
    }
    

    【讨论】:

    【解决方案8】:

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

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

    【讨论】:

    • 使用memset 更快:memset(arr, 0, bins * sizeof(int)); 另外,我怀疑你的for 循环不应该是包容性的(即&lt; bins 而不是&lt;= bins)。
    【解决方案9】:

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

    初始化变量数组的最好方法是这样的:

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

    memset 是一个非常快速的标准库函数,用于初始化内存(在上述情况下为 0)。 sizeof(boardAux) 返回boardAux 占用的字节数。 sizeof 始终可用,但 memset 需要 #include &lt;string.h&gt;。是的 - sizeof 允许可变大小的对象作为参数。

    请注意,如果您有一个普通数组(不是可变长度)并且只想将内存初始化为零,那么您永远不需要嵌套括号,您可以像这样简单地初始化它:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-28
      • 1970-01-01
      • 1970-01-01
      • 2019-02-21
      • 2012-12-20
      相关资源
      最近更新 更多