C语言指向堆和栈指针分析(四十九)
C语言 分析 指针 指向
2023-09-14 09:09:58 时间
结论:函数可以返回局部变量的值,但是不能返回指向栈内存的指针。
原因:
局部变量的作用域为函数内部,函数执行结束,操作系统会自动释放栈上的局部变量。并且函数返回的是局部变量的值拷贝。
但是如果返回局部变量的地址,那么返回的是该局部变量地址的值拷贝,但是函数运行结束,该拷贝指针所指向的栈内容已经被释放即为野指针,对野指针所指向内容的操作都会造成段错误.
函数是可以返回指向堆内存的指针,但是这需要在调用者在函数外手动进行内存的释放,可以通过指针传递来解决。
一般来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。
因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确来说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。
总结如下:
(1)返回指向字符串常量的指针
(3)在函数中,允许返回局部变量的值,不允许返回局部变量的地址
(4)在函数中,如果函数的返回值非要是一个局部变量的地址,那么该局部变量一定要申明为static类型。
#include <iostream>
#include <stack>
#include <string.h>
using namespace std;
int fun0(){
int cc = 5; //在栈上分配内存
//可以返回局部变量,因为返回的是cc是拷贝一份的值,fun0()函数结束后,cc释放掉,副本值可以返回正确的值.
return cc;
}
int* fun(){
int cc = 5;//在栈上分配内存
//返回cc的地址,fun()函数结束时,cc在栈上分配的内存会出栈,释放掉,这时返回的地址是一个野指针
return &cc;
}
int* fun1(){
int cc = 5;
int *p = &cc;
return p;
}
int* fun2(){
int cc = 66;//在栈上分配内存
int *p = &cc;
return p;//返回cc的地址,fun()函数结束时,cc在栈上分配的内存会出栈,释放掉,这时返回的地址是一个野指针
}
int main(){
//OK
int cc = fun0();
printf("%d\n", cc);
//Error
int *m = fun();
printf("%d\n", *m);
#if 0
//way 1:OK;这里虽然是正确的,但是下面的栗子确实错误的,概率问题,不能返回局部变量的指针
int *p = fun1();
printf("%d\n", *p);
int *q = fun2();
printf("%d\n", *q);
#else
//way 2:Error ;可能分配堆栈顺序问题,返回结果都是66
int *p = fun1();
int *q = fun2();
printf("%d\n", *p);
printf("%d\n", *q);
#endif
return 0;
}
总结:不能返回局部变量的指针是有前提的:
1.可以返回指针指向全局变量、堆上分配(new,malloc)、常量区(如:"123")、静态区(static)的指针
2.不能返回指向栈的指针,因为栈随函数执行完成,出栈自动回收内存,会造成指向的是一个无效地址,导致段错误
相关文章
- C语言指针错误使用分析
- 传智播客c/c++公开课学习笔记--C语言与木马恶意代码分析和360安全防护揭秘
- 分形几何算法和实现(C语言)
- ZZNUOJ_用C语言编写程序实现1159:逆序输出数组元素(指针专题)(附完整源码)
- ZZNUOJ_用C语言编写程序实现1508:学渣学霸(附完整源码)
- 【C语言】变量本质分析
- 【C语言】数据类型本质分析
- C语言面试 写一个函数查找两个字符串中的第一个公共字符串
- Python重写C语言程序100例--Part6
- C语言之perror与strerror区别(三十三)
- C语言逆向——常量字符串的赋值copy分析
- C语言基础----C语言中字符串处理库函数memset详解
- C语言: 输入一批正整数(以零或负数为结束标志),求其中的奇数和。要求定义和调用函数int even(int n)判断整数n的奇偶性,当为奇数时返回1,否则返回0。
- 【维生素C语言】第四章 - 数组
- 【维生素C语言】第七章 - 结构体
- 【重温经典C语言】~c语言中%x、%c、%d、%x等等等、c语言取地址符&的作用、C语言中的 联合体
- 2D FFT、RFFT的C语言实现