原则:
能否正常返回这个值,要看这个值的内容或指向的内容是否被回收,导致空指针或者真实内容被擦除。【一旦返回值有指针或者地址,就需要着重考虑,而返回一个值是一般都可以的,可参考C++的临时变量】
下面对不同情况说明。
1、返回指向常量的指针
#include <stdio.h> char *returnStr() { char *p="hello world!"; return p; } int main() { char *str; str=returnStr(); printf("%s ", str); return 0; }
这个没有任何问题,因为"hello world!"是一个字符串常量,存放在只读数据段,把该字符串常量存放的只读数据段的首地址赋值给了指针,所以returnStr函数退出时,该该字符串常量所在内存不会被回收,故能够通过指针顺利无误的访问。
2、不能返回数组
#include <stdio.h> char *returnStr() { char p[]="hello world!"; return p; } int main() { char *str; str=returnStr(); printf("%s ", str); return 0; }
"hello world!"是局部变量存放在栈中,而这里的p是指向"hello world!"的首地址。当returnStr函数退出时,栈要清空,局部变量的内存也被清空了,所以这时的函数返回的是一个已被释放的内存地址,所以有可能打印出来的是乱码。
3、返回普通值
int func() { int a; .... return a; //允许 } int* func() { int a; .... return &a; //无意义,不应该这样做 }
直接返回a,返回的是值,结果存储在临时变量中;返回&a时,是a的地址,而函数结束后,栈要清空,a的内存也被清空了,故结果肯定会异常。
4、可以把地址设置成static可正常返回
#include <stdio.h> char *returnStr() { static char p[]="hello world!"; return p; } int main() { char *str; str=returnStr(); printf("%s ", str); return 0; }
5、可以返回指向堆内存的指针
char *GetMemory3(int num) { char *p = (char *)malloc(sizeof(char) * num); return p; } void Test3(void) { char *str = NULL; str = GetMemory3(100); strcpy(str, "hello"); cout<< str << endl; free(str); }