1

所以在我的源文件中,我有 folowin 函数:

void update(state* old_state, state* measurement, uint32_t size)
{
  state new_state[size];
  //some function using measurement and old_state and returning the result in newstate

  arm_fadd_32(measurement,old_state,newstate,size);

// 其余代码 }

现在编译器会抛出一个错误,指出 error#28:expression 必须有一个常量值。我认为这是因为即使在方法内部,局部变量的大小没有改变,编译器在定义大小时也期望一个常量。我尝试了以下方法:

int const a = size; 

然后尝试重新初始化它说常量值未知。我在互联网上做了一些研究,似乎没有使用 malloc 的更简单的方法,我不想这样做,因为我正在使用一些嵌入式应用程序的代码。

有没有办法在不真正使用 malloc 的情况下避免这个问题?提前谢谢各位!

4

4 回答 4

4

不,不是。如果编译器不允许变长数组,则意味着它需要一个编译时常量。

C99 支持 VLA,这可能不是您正在使用的。

int const a声明一个常量变量(哈哈!),但它绝不是编译时常量。您将需要使用malloc.

于 2012-10-02T21:34:32.663 回答
4

从 1990 ISO C 标准开始,数组的大小必须是一个常量整数表达式。注意“常数”,而不是const. 常量表达式(大致)是其值在编译时已知的表达式;const,虽然它来自同一个词根,但实际上只是意味着“只读”。

1999 年的标准添加了 VLA(可变长度数组),这将使您的代码合法。VLA 的一个缺点是没有检测分配所需空间失败的机制。如果分配失败,您的程序行为未定义。(如果幸运的话,它可能会崩溃。)

现在大多数 C 编译器都支持大部分 C99 标准。您可能需要一个命令行选项来启用它。另一方面,Microsoft 的 C 编译器仅支持 C90,以及极少数 C99 特定的功能,并且 Microsoft 已表示他们没有计划更改这一点。如果您让我们知道您使用的是什么编译器,我们可能会更有帮助。

您可以使用malloc()在堆上分配动态大小的数组:

state *new_state = malloc(size * sizeof *new_state);
if (new_state == NULL) {
    // allocation failed, handle the error somehow
}

请注意,它malloc()返回一个空指针来指示分配失败,即使您的编译器支持 VLA,这也比 VLA 更有优势。

于 2012-10-02T21:36:01.903 回答
2

您的 C 编译器显然不支持 C99 VLA。这意味着数组必须具有在编译时已知的维度。而你的没有。

显然你可以在堆上分配malloc. 但是您已经声明出于性能原因您不想这样做。如果你真的必须有堆栈分配的内存,其大小是在运行时确定的,那么你需要使用alloca.

当心那里alloca充满危险。堆栈溢出在使用 时是一个永远存在的危险alloca,就像在使用 C99 VLA 时一样。

于 2012-10-02T21:37:11.940 回答
1

在 C89 中,数组大小必须是常数。const限定符不将对象限定为常量,而是将其限定为只读。

在 C99 中,您可以拥有非恒定数组大小,这些数组称为可变长度数组 (VLA)。

于 2012-10-02T21:35:24.263 回答