当我们返回栈空间地址时会报错,为什么呢?那让我们先看一下什么是返回栈空间地址?
下面是错误示范:
vs2022版演示
出现问题,不要慌,那我们就先调试一下。
经过调试我们惊奇的发现,编译器竟然没有报错。那让我们一步一步来分析这段代码。
1.程序从主函数开始,调用Test函数。
2.进入Test函数定义一个字符型指针str 置为空指针,str=调用GetMory函数的返回值。
3.进入GetMory函数,字符型的数组p 赋值为“hello”,return p;p是一个数组,return p;p是数组名,实际是返回的数组的首元素地址‘h’的地址。正好str也是一个指针,正好接收地址,再打印str
按理来说没什么问题啊,但为什么会打印 烫烫烫烫烫烫烫烫呢?
其实是因为GetMory函数中 char p[]="hello";中p是一个局部的数组,在栈区上开辟的空间。当GetMory函数结束时,p就会自动销毁,也就是说p所开辟的空间就会还给操作系统,但p那块空间的地址还存在而且传给了str,当str顺着这个地址访问时,地址原来的空间已经被销毁了,不存在了,但我还要去访问那块空间,从而会出现非法访问问题,导致程序出错。
改进方法:
可以在 char p[]="hello"前面加上一个static修饰,使p延长了生命周期。
那有同学会问,如果返回的不是地址,是一个变量,能不能这样做呢?答案是肯定哒,yes
上面就是栈空间地址问题的讲解,总结一下简单可以理解为,函数调用如果返回值为一个局部地址,就会出错,除非返回变量,或加上static修饰。
另外加一个知识点,如果空间是在堆区上开辟的,堆区只有 free来释放空间,所以不存在返回占栈空间地址问题。