函数返回局部变量/局部指针

c语言 返回局部变量 局部指针 局部数组

内存四区模型

  讨论这个问题之前,一定要理解堆区和栈区的工作原理,数据的存储区域(参考内存四区模型),另外一定不要返回局部对象或变量的引用和指针。

局部变量

  局部变量分局部自动变量和局部静态变量,由于c返回的是值,因此返回一个局部变量是可以的,无论自动还是静态,因为这时候返回的是这个局部变量的值。另外,函数返回局部变量时实际上是返回变量值的拷贝。a为局部变量,在栈区存储,虽然在函数调用结束后所在内存会被释放回收掉,但返回值不是访问地址,而是a的拷贝副本。

1 int INTtest(){
2     int a = 10;
3     return a;
4 }

局部指针

  局部指针跟上面所述的局部变量一样。可以返回一个局部指针的值,也可以返回一个局部静态指针的地址,但不应该返回一个局部自动指针的地址,除非自动指针的地址指向数据区或堆区

  返回值为局部指针,可以分为:(1)声明局部变量,返回其地址;(2)声明局部数组,返回数组名;(3)声明局部指针,返回该指针。

  1.返回局部变量地址,局部变量分为自动和静态局部变量,不应该返回指向局部自动变量的指针,因为函数调用结束后栈上声明的局部自动变量被抛弃,这个指针指向一个不再存在的对象,是无意义的。但可以返回指向局部静态变量的指针,因为静态变量存在数据区,它的生存期从定义起到程序结束。

  2.返回数组名,与局部变量相同(自动和静态),调用的结果指向栈上声明的数组的首地址,函数结束后自动数组内存释放掉,将无法对其进行访问(某些编译器Release下可以访问,但理论上是没有意义的),但静态数组可以。

  3.返回指针,调用结果指向该指针指向的内存,在函数结束后在栈上声明的指针也会被释放掉,但应该注意原指针指向的内存地址,若改地址同样是栈上声明的,则无法访问,如果是数据区或堆区的内容,则可以访问。

  1和2比较容易理解,这里不再进行举例,仅对第3种情况的数据区和堆区进行说明。

  数据区:返回指针,但指针指向的内存地址存储在数据区(常量区)

 1 char * test(){
 2     char *arr = "hello world"; //字符常量
 3     //static char arr[] = "hello world!";
 4     return arr;
 5 }
 6 
 7 void  test_(){
 8     char *s = test();
 9     printf("s = %s\n", s);
10 }
11 
12 int main(){
13     test_();
14         return 0;      
15 }

  堆区:返回指针,指针指向的内存地址存储在堆区,没有手动释放前都可以访问到。

 1 char *getstring(){
 2     char *p;
 3     p = malloc(100);
 4     memset(p, 0, 100);
 5     strcpy(p, "hello");
 6 
 7     return  p;
 8 }
 9 
10 void test(){
11     char *ret = getstring();
12     printf("%s\n", ret);
13     free(ret);
14     ret = NULL;
15 }
16 
17 int main(){
18 
19     test();
20 
21     system("pause");
22     return 0;
23 }

  如果指针指向的内存是在函数内部申请的,基本不干返回指针这种事,做这种事情很有可能是在给自己找麻烦,多数做的都是在可以释放的地方申请好内存,通过指针传递进函数,申请和释放都在同一函数中。上面的函数,可以修改如下:

 1 void getstring01(char *p){
 2     strcpy(p, "hello");
 3 }
 4 
 5 void test01(){
 6     char *p = NULL;
 7     p = malloc(100);
 8     memset(p, 0, 100);
 9     //char *ret = NULL;
10     getstring01(p);
11     printf("%s\n", p);
12     free(p);
13     p = NULL;
14 }
15 
16 
17 int main(){
18         test01();
19         return 0;
20 }

 

posted @ 2018-12-21 11:30  两猿社  阅读(8315)  评论(0编辑  收藏  举报