返回值是数组的函数
前言
我们先来看一下,根据直观直觉写出来的错误代码是怎么样的
#include<stdio.h>
char* func(void){
char a[15]="hello,world";
return a;
}
int main(){
char* arr=func();
printf("%s",arr);
}
[Warning] function returns address of local variable [-Wreturn-local-addr]
错误结果
`t
此处表示,返回了一个局部变量的地址,也就是说,返回局部变量的地址是非法的。这里的知识与数据结构“栈”有关,我们可以暂时理解成如下语言:当函数返回一个值的时候,可以把这个值传递到外界,那么函数返回数组时,相当于返回一个地址。此时,地址和值是等价的,函数一样把地址传到了外界。但是函数的生命周期在return完之后就已经结束了,因此内存被释放。地址的值被传递出去,但它指向的值已经被销毁,这个地址代表的地方已经陷入混乱无序的状态,可能产生未定义行为,输出乱码。
所以,如果想有效地返回数组,就必须返回一个内存不会随函数结束而释放的地址。
有两种方法,第一种是使用malloc函数,第二种是使用静态数组。因为静态数组在多次调用时会发生一些错误,所以我们只介绍第一种方法。
malloc
本体
void* malloc(size_t size);
malloc表示分配一块大小为size的内存出来,void*类型需要操作者显式转换成需要的类型
示例代码
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
char* func(void){
char*a=(char*)malloc(15*sizeof(char));
strcpy(a,"hello,world.");
return a;
}
int main(){
char* arr=func();
printf("%s",arr);
}
结果
hello,world.
解释:malloc分配出了一块15字节大小的内存,而指针a指向这个地址,函数返回a,这个地址并没有失效,所以可以正常返回。
内存泄漏
提到malloc就不得不提一个问题:内存泄漏。在前面我们提到,malloc分配出了一块内存。那么假如储存这块分配出的内存地址的指针被重新赋值,地址丢失,我们就再也找不到这块内存了,即这块内存泄漏了。假如这件事情重复发生,可用内存会越来越少,导致程序崩溃。因此应当在地址丢失之前释放malloc分配的空间,这件事情可以用free实现
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
char* func(void){
char*a=(char*)malloc(15*sizeof(char));
strcpy(a,"hello,world.");
return a;
}
int main(){
char* arr=func();
printf("%s",arr);
free(arr);
}