对于最近遇到的一些函数返回指针问题归类总结,希望对各位读者也能有所作用。
首先从一个选择题开始:
int main()
{
char *str = NULL;
char *fun(void);
str = fun();
printf(“%s\n”,str);
return 0;
};
char* fun(void)
{
1. char str[] = "i love you";
2. char str[] = {'i',' ','l','o','v','e',' ','y','o','u'};
3. static char str[] = "i love you";
4. static char str[] = {'i',' ','l','o','v','e',' ','y','o','u'};
5. char *str = "i love you";
6. static char *str = "i love you";
7. char str[] = "i love you";char *q = (char *)malloc(10 * sizeof(char)); q = str;
8. char *str = (char *)malloc(10 * sizeof(char));memcpy(str,"i love you",10);
char *q=str;
return q;
}
上面的哪个选项是对的,是不是有些眼花缭乱了,基础比较好的很快就判断出来,3,4,5,6,8是正确的,1,2,7是错误的用法
下面一一解释:
1. char str[] = “i love you”;
str是一个char类型数组首地址,程序执行到此处时,字符串“i love you”复制到str指向的存储空间里,属于动态存储,它是存放在栈(statck)空间内,一旦其所在的函数调用结束,那么str的栈空间被释放掉,所以上面code中返回的指针q指向的地址空间已经被释放掉,即变成野指针。
2. char str[] = {‘i’,’ ‘,’l’,’o’,’v’,’e’,’ ‘,’y’,’o’,’u’};
这个跟1的道理相同,只不过1中是用字符串常量赋值,2中是单个字符赋值,但是str指向的存储空间都是在statck空间中,存储方式都一样即动态存储。
3. static char str[] = “i love you”;
这里多了一个static,static在这里的用途是规定str的作用域是其所在的函数内,str数组开辟的空间存储方式是静态存储,该数组变量在程序退出之前会一直存在,所以返回的指针p指向的地址空间会一直存在直到程序退出。
4. static char str[] = {‘i’,’ ‘,’l’,’o’,’v’,’e’,’ ‘,’y’,’o’,’u’};
参考3的解释
5. char *str = “i love you”;
str本身是放在栈区,字符串“i love you”是存放在常量存储区里,该空间直到程序结束才会释放,指针str指向该空间,所以返回的指针p指向的地址空间会一直存在。
6. static char *str = “i love you”;
str本身存放在全局(静态)数据区,同时字符串“i love you”存放在常量存储区,两者都是到程序结束时空间才会释放
7. char str[] = “i love you”;char q = (char )malloc(10 * sizeof(char)); q = str;
这里的定义有点偷梁换柱的意思,写这段code的人本来是返回q指向的空间如果不手动释放会一直存在,但是最后q=str则让q改变了指向,导致结果与1中的作用相同了。
8. char str = (char )malloc(10 * sizeof(char));memcpy(str,”i love you”,10);
str指向的存储空间如果不手动释放会一直存在,所以8正确
经过上面的解释可以总结一下,对于返回指针类型的函数尽量按照下面几种方式来使用
1 使用malloc分配空间
2 使用static变量指针
3 使指针指向常量空间
4 指向全局变量的指针
当然还有二级指针的传递等,有兴趣的读者可以继续研究………