函数返回局部变量地址为什么危险
2026/9/4大约 2 分钟
函数返回局部变量地址为什么危险
这是 C 语言指针中一个非常经典的错误:
不能返回局部变量的地址。
一、为什么?
例如:
int *func(void)
{
int arr[10];
return arr;
}调用:
int *p = func();问题就在这里。
arr 是 func() 的局部变量,通常位于函数栈帧中:
func()
┌──────────────┐
│ arr[10] │
└──────────────┘
↑
栈函数执行结束:
func()
↓
return
↓
栈帧销毁
↓
arr 的生命周期结束但:
int *p = func();中的 p 仍然保存着原来的地址。
于是:
arr 已经不存在
↑
│
└── p 还指向这里此时 p 就成了悬垂指针(dangling pointer)。
二、为什么还能“打印出东西”?
例如:
int *func(void)
{
int arr[3] = {1, 2, 3};
return arr;
}
int main(void)
{
int *p = func();
printf("%d\n", p[0]);
}有时候你甚至能看到:
1这并不代表程序正确。
函数返回后,那块栈空间只是不再属于 arr,内存中的旧数据可能暂时还没被覆盖。
下一次函数调用:
旧 arr 的空间
↓
被其他函数继续使用
↓
原来的内容被覆盖所以结果可能变成:
1也可能:
随机值甚至导致其他错误。
这属于:
通过失效对象访问内存,产生未定义行为。
三、正确做法
方法一:让调用者提供数组
void func(int *arr)
{
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
}调用:
int arr[3];
func(arr);数组由调用者管理,函数结束后仍然有效。
方法二:使用 static
int *func(void)
{
static int arr[3] = {1, 2, 3};
return arr;
}static 局部变量不在普通栈帧中,函数返回后仍然存在。
但它有共享状态:
第一次调用
↓
修改 arr
第二次调用
↓
还是同一个 arr并发或多次调用时要特别注意。
方法三:动态分配
int *func(void)
{
int *p = malloc(3 * sizeof(int));
if (p == NULL)
return NULL;
p[0] = 1;
p[1] = 2;
p[2] = 3;
return p;
}调用者使用完必须:
free(p);不过在 STM32/RTOS 中,动态内存是否适合要看具体场景。
四、最终记忆
局部变量
↓
通常属于函数栈帧
↓
函数返回
↓
栈帧销毁
↓
局部变量生命周期结束所以:
int *func(void)
{
int arr[10];
return arr; // ❌
}本质问题就是:
地址还在,但地址指向的对象已经死了。
所以返回后得到:
悬垂指针
↓
再通过它访问
↓
未定义行为不要返回指向函数局部变量的地址。地址能留下,不代表对象还活着。

