不能在函数中返回一个局部变量的地址:warning :address of local variable returned

#include<stdio.h>
#include<string.h>
char *intToString(void){
	char string[] = "hello world!";
	return string;
}
int main(void){
	puts(intToString());
	return 0;
}

执行时会出现下述问题:

在这里插入图片描述

"hello world!"字符串字面量是存储在静态存储区的,函数结束也不会被释放,但是,使用字符数组的时候,会在栈区新建一个备份,所以在函数结束时就被自动被销毁了(返回的是一个地址,但是在这个函数结束的时候,这个地址指向的那块内存空间放置的内容被释放了,所以通过那个返回的地址已经找不到那块地址对应的内容了),所以肯定是不对的(静态申请内存的变量不能跨函数使用)
解决办法四种

//方法1
#include<stdio.h>
#include<string.h>

char string[] = "hello world!";

char *intToString(void){
	return string;
}
int main(void){
	puts(intToString());
	return 0;
}

方法1可以是因为全局变量string具有静态存储区,整个程序执行结束才会释放。

//方法2
#include<stdio.h>
#include<string.h>
char *intToString(void){
	char *string = "hello world!";
	return string;
}
int main(void){
	puts(intToString());
	return 0;
}

方法2可以是因为,当使用指向一个字符串字面量("“括起来的部分,例如"hello world!”)的字符指针的时候,该字符串字面量是存储在静态存储区的(堆区),所以返回的地址指向的内容(在堆区)不会被释放,因此能够找到(但是这种写法有一个缺点,即定义好了字符串指针之后,就不能改变其指向的字符串了,改了之后可能会出现意想不到的错误)。

//方法3
#include<stdio.h>
#include<string.h>
char *intToString(void){
	char string[] = "hello world!";
	//申明为静态变量,静态变量存在data区里面
	static char temp[20];
	strcpy(temp,string);
	return temp;
}
int main(void){
	puts(intToString());
	return 0;
}

方法3,变量temp静态存储期,和方法1类似。

//方法4
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
char *intToString(void){
	char string[] = "hello world!";
	//为temp动态分配内存(动态申请内存的变量可以跨函数使用)
	// malloc分配的内容在堆区,temp还是分配在栈区
	char *temp=(char *)malloc(20*sizeof(char));
	temp[0] = string[0];
	strcpy(temp,string);
	return temp;
}
int main(void){
	puts(intToString());
	return 0;
}

文件作用域的变量,静态变量,全局const常量,动态申请的内存都是在整个程序结束才释放

static当用于函数定义时或者用于代码块之外的变量申明时,用于修改标识符的链接属性,从外部链接变成内部链接,但是存储类型和作用域不受影响,用这种方式申明的函数或变量只能在他们的源文件中访问。当它用于代码块内部的变量申明时,用于修改变量的存储类型,从自动变量修改为静态变量,但是链接属性和作用域不受影响。

说明:局部变量的作用域在函数的内部,函数返回后,局部变量内存已经释放掉了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。故函数是可以返回局部变量的。但是如果函数返回的是局部变量的地址(指针)的话,程序运行就会报错。由于只是把指针(地址)复制后返回了,而指针指向的内存(存储的内容)已经被释放了,这样指针无访问该内存的权限,调用后就会报错。准确的说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的(因为堆内存里面的内容是在整个程序结束才释放,static存在data区里面,也是在整个程序结束才释放))。

参考

C专家编程

  • 32
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值