所以在我的源文件中我有以下功能:
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);
//其余代码 }
现在编译器抛出一个错误说 错误#28:表达式必须具有常量值。 我认为这是因为即使在方法内部大小局部变量没有改变,编译器在定义大小时期望一个常量。 我尝试过以下方法:
int const a = size;
然后尝试重新初始化它说恒定值是未知的。 我在互联网上做了一些研究,似乎没有使用malloc没有更简单的方法,我不想这样做,因为我正在使用某些嵌入式应用程序的代码。
有没有办法在没有真正使用malloc的情况下避免这个问题?先谢谢你们!
答案 0 :(得分:4)
不,不是真的。如果编译器不允许变长数组,则意味着它需要编译时常量。
在C99中支持VLA,这可能不是您正在使用的。
int const a
声明一个常量变量(哈哈!),但它绝不是编译时常量。您需要使用malloc
。
答案 1 :(得分:4)
从1990 ISO C标准开始,数组的大小必须是常量整数表达式。注意“常数”,而不是const
。常量表达式(大致)是一个在编译时已知的值; const
虽然来自同一个词根,但实际上只是“只读”。
1999标准添加了VLA(可变长度数组),这将使您的代码合法。 VLA的一个缺点是没有机制来检测分配所需空间的失败;如果分配失败,则程序行为未定义。 (如果你很幸运,可能会崩溃。)
如今,大多数C编译器都支持大多数C99标准;您可能需要一个命令行选项来启用它。另一方面,微软的C编译器仅支持C90,并且只支持极少数特定于C99的功能,微软表示他们没有计划改变它。如果你让我们知道你正在使用什么编译器,我们可能会更有帮助。
您可以使用malloc()
在堆上分配动态大小的数组:
state *new_state = malloc(size * sizeof *new_state);
if (new_state == NULL) {
// allocation failed, handle the error somehow
}
请注意,malloc()
返回一个空指针以指示分配失败,即使您的编译器支持它,这也优于VGA。
答案 2 :(得分:2)
您的C编译器显然不支持C99 VLA。这意味着数组必须在编译时具有已知的维度。你的没有。
显然,您可以使用malloc
在堆上进行分配。但是你已经声明,出于性能原因,你不想这样做。如果你真的必须有堆栈分配的内存,其大小是在运行时确定的,那么你需要使用alloca
。
请注意alloca
充满危险。使用alloca
时,Stack Overflow是一个永远存在的危险,就像使用C99 VLA时一样。
答案 3 :(得分:1)
在C89中,数组大小必须是常量。 const
限定符不会将对象限定为常量,而是为只读。
在C99中,您可以拥有非常量数组大小,这些数组称为可变长度数组(VLA)。