服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - 详解C语言中return返回函数局部变量的问题

详解C语言中return返回函数局部变量的问题

2021-12-24 14:33精致的灰(>_<) C/C++

本文主要介绍了C语言中return返回函数局部变量的问题,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

在计算机中,释放空间并不需要将空间中的内容全部置成0或者1,而是只要设置这一块空间的数据无效即可。比如在下载文件时需要花很长时间,但是删除文件却只要几秒钟,这是因为操作系统只是把文件标识(文件头链接)删掉了,文件原文还保留着,我们没了文件标识就找不到这个文件了。所以删除后的文件,还可以用特殊的办法被找回来。

这也就意味着,当函数结束调用的时候,函数中的局部变量实际上还是在的,只是函数原来的空间还给编译器(释放)了,也就是说函数中的局部变量是可以被编译器修改的。
虽然函数结束后空间还给了编译器,但是我们依然可以通过指针找到对应的局部变量的空间。

 

return返回栈区局部变量的指针

通过上面的分析,如果我们返回局部变量的指针,是不是可以直接找到这个局部变量呢?

返回了一个局部变量的指针,而恰好局部变量偏偏又在函数结束后销毁,但指针并没有被销毁,而是被返回,那也就是说,指针指向的正是一个被销毁了的对象。

比如下面的代码:

#include <stdio.h>
char* returnStr()
{
  char p[] = "hello world!";
  return p;
}
int main()
{
  char* str;
  str = returnStr();
  printf("%s\n", str);
  return 0;
}

详解C语言中return返回函数局部变量的问题

可以看到原来p的空间已经被修改了,但是很奇怪,是谁进行的修改呢?

通过调试可以发现,当函数结束后,运行printf打印之前,str指向的空间中的字符串是在的:

详解C语言中return返回函数局部变量的问题

但是一运行printf打印操作,str指向的空间中的字符串就会被修改:

详解C语言中return返回函数局部变量的问题

这其实很好解释,因为printf本身也是一个函数,函数都是在栈区开辟的,而函数开辟的空间叫做栈帧,函数结束栈帧就还给了编译器:

详解C语言中return返回函数局部变量的问题

了解了这些,那是不是只要我们多建立几个函数栈帧,是不是就可以使returnStr的函数栈帧不被覆盖了?答案是肯定的:

#include <stdio.h>
char* fun6()
{
  char p[] = "hello world";
  return p;
}
char* fun5()
{
  return fun6();
}
char* fun4()
{
  return fun5();
}
char* fun3()
{
  return fun4();
}
char* fun2()
{
  return fun3();
}
char* fun1()
{
  return fun2();
}
char* fun()
{
  return fun1();
}
int main()
{
  char* str;
  str = fun();
  printf("%s\n", str);
  return 0;
}

详解C语言中return返回函数局部变量的问题

详解C语言中return返回函数局部变量的问题

不过随着函数栈帧的逐渐增多,原来的fun6函数空间迟早也会被覆盖。

在函数体内定义的局部变量是有临时性的,当局部变量释放后随时都有可能会被修改,所以我们不能通过指针使用已经被释放的局部变量。

 

return返回栈区局部的临时变量

如果我们不返回指针,而是返回局部变量会怎么样呢?
按理来说局部变量也会被修改。

#include<stdio.h>
int test()
{
	int a = 10;
	return a;
}
int main()
{
	int b = test();
	printf("%d", b);
}

详解C语言中return返回函数局部变量的问题

通过反汇编可以看到,局部变量a的值10通过寄存器交给了调用的b,所以即使局部变量a空间的10已经被修改,也不会影响b的内容:

详解C语言中return返回函数局部变量的问题

 

return只读数据段和static数据

如果返回只读字符串则不会被覆盖,因为数据不是在栈区,而是在静态区:

详解C语言中return返回函数局部变量的问题

同理如果将字符串用static修饰也是如此:

详解C语言中return返回函数局部变量的问题

另外,返回堆内的指针也是可以的。

到此这篇关于详解C语言中return返回函数局部变量的问题的文章就介绍到这了,更多相关C语言return返回函数局部变量内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_52670477/article/details/119980530

延伸 · 阅读

精彩推荐
  • C/C++详解c语言中的 strcpy和strncpy字符串函数使用

    详解c语言中的 strcpy和strncpy字符串函数使用

    strcpy 和strcnpy函数是字符串复制函数。接下来通过本文给大家介绍c语言中的strcpy和strncpy字符串函数使用,感兴趣的朋友跟随小编要求看看吧...

    spring-go5642021-07-02
  • C/C++学习C++编程的必备软件

    学习C++编程的必备软件

    本文给大家分享的是作者在学习使用C++进行编程的时候所用到的一些常用的软件,这里推荐给大家...

    谢恩铭10102021-05-08
  • C/C++C语言中炫酷的文件操作实例详解

    C语言中炫酷的文件操作实例详解

    内存中的数据都是暂时的,当程序结束时,它们都将丢失,为了永久性的保存大量的数据,C语言提供了对文件的操作,这篇文章主要给大家介绍了关于C语言中文件...

    针眼_6702022-01-24
  • C/C++C/C++经典实例之模拟计算器示例代码

    C/C++经典实例之模拟计算器示例代码

    最近在看到的一个需求,本以为比较简单,但花了不少时间,所以下面这篇文章主要给大家介绍了关于C/C++经典实例之模拟计算器的相关资料,文中通过示...

    jia150610152021-06-07
  • C/C++深入理解goto语句的替代实现方式分析

    深入理解goto语句的替代实现方式分析

    本篇文章是对goto语句的替代实现方式进行了详细的分析介绍,需要的朋友参考下...

    C语言教程网7342020-12-03
  • C/C++C++之重载 重定义与重写用法详解

    C++之重载 重定义与重写用法详解

    这篇文章主要介绍了C++之重载 重定义与重写用法详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...

    青山的青6062022-01-04
  • C/C++C语言实现电脑关机程序

    C语言实现电脑关机程序

    这篇文章主要为大家详细介绍了C语言实现电脑关机程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    xiaocaidayong8482021-08-20
  • C/C++c++ 单线程实现同时监听多个端口

    c++ 单线程实现同时监听多个端口

    这篇文章主要介绍了c++ 单线程实现同时监听多个端口的方法,帮助大家更好的理解和学习使用c++,感兴趣的朋友可以了解下...

    源之缘11542021-10-27