我在一个函数的代码中遇到了问题,我想声明一个数组,但它失败了。经过一些调试,我发现它在反汇编窗口中使用了malloc,所以我增加了堆大小,它工作得很好!
所以我的问题是,为什么keil使用Heap作为局部变量?
这是变量声明代码:
uint8_t result[data->capacityBytes];
memset(result, 0, sizeof(result));
我添加了标志C99
您的数组具有动态大小,即编译器直到运行时才知道它会有多大。这是C99中引入的一个称为可变长度阵列(VLA(的功能。
根据Keil的文档(请参阅注释(,这样的数组是由这个编译器在堆上分配的。(其他人可能会在堆栈上分配。其他人可能根本没有实现这个功能——它在C11中变成了可选的。(
您的局部变量result
以以下方式声明:
uint8_t result[data->capacityBytes];
假设data->capacityBytes
不是常数,这意味着result
将是一个可变长度数组(VLA(,这将解释您正在使用的编译器的行为。
然后,您假设存储区中的可变位置是标准化的,不幸的是,这是不正确的,如以下答案所述:
实际上,C语言并没有定义任何变量的存储位置。但是,它定义了三个存储类:静态、自动和动态。
变量的存储位置取决于编译器对源代码的解释。
另请参阅有关可变长度数组的维基百科条目
内存
分配
- GNU C编译器在堆栈上为具有自动存储持续时间的VLA分配内存。与堆分配相比,这是一个更快、更直接的选项,大多数编译器都使用它
- VLA也可以在堆上分配,并使用指向该块的指针进行内部访问