可变长度数组及其风险
2026/8/23大约 2 分钟
可变长度数组及其风险
VLA(Variable Length Array)是 C99 引入的特性,数组长度可以在运行时确定。
一、什么是 VLA?
void func(int n)
{
int arr[n];
}这里 n 不是编译期常量:
func(10); // arr[10]
func(100); // arr[100]数组大小在运行时确定。
二、VLA 和动态数组的区别
VLA:
void func(int n)
{
int arr[n];
}通常分配在栈上,函数结束后自动释放。
动态数组:
int *arr = malloc(n * sizeof(int));分配在堆上,需要手动:
free(arr);所以:
VLA
→ 栈
→ 自动释放
malloc
→ 堆
→ 手动释放三、VLA 最大的问题:栈溢出
例如 STM32 任务栈只有几 KB:
void task(int n)
{
uint8_t buf[n];
}如果:
n = 8192就可能直接占用 8 KB 栈空间。
结果:
VLA过大
↓
栈空间不足
↓
Stack Overflow尤其 n 来自外部输入时,风险更大。
四、VLA 不是动态扩容数组
int arr[n];只是:
运行时决定一次数组大小。
它不会自动:
10 → 20 → 40 → 80自动扩容。
需要动态增长时,应该考虑:
malloc()
realloc()
free()五、嵌入式中的使用建议
MCU 尤其是 FreeRTOS 任务的栈空间通常比较有限,因此:
void task(int n)
{
uint8_t buf[n]; // ⚠️
}不推荐随意使用。
更稳妥的是:
#define BUF_SIZE 256
uint8_t buf[BUF_SIZE];或者在确实需要运行时分配时使用动态内存。
六、最终记忆
VLA
↓
数组大小运行时确定
↓
通常位于栈上
↓
函数结束自动释放最大风险:
VLA过大
↓
栈溢出VLA 解决的是“数组长度运行时才知道”,不是“动态自动扩容”。在 MCU 中要特别警惕栈空间。

