C++ 函数中返回字符串的一个陷阱

Posted 左百工

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ 函数中返回字符串的一个陷阱相关的知识,希望对你有一定的参考价值。

 1 #include<iostream>
 2 using namespace std;
 3 char * getname(void);
 4 int main()
 5 {
 6     char * name;
 7     name = getname();
 8     cout << "My name is : " << name << endl;
 9     cout << "---------华丽的分割线----------" << endl;
10     return 0;
11 }
12 char * getname()
13 {
14     char get_name[30];
15     cout << "Enter your name :";// a word
16     cin >> get_name;
17     return get_name;
18 }

可能第一眼看上去没什么毛病,BUT  getname()里面的get_name是一个字符串数组。在函数return之后这个get_name会释放内存(因为她在栈中,函数执行玩会弹栈)。所以main函数中的name变成了一个野指针,这是一个很危险的操作。

解决办法:返回一个在堆中的地址。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 char * getname(void);
 5 int main()
 6 {
 7     char * name;
 8     name = getname();
 9     cout << "My name is : " << name << endl;
10     cout << "---------华丽的分割线----------" << endl;
11     return 0;
12 }
13 char * getname()
14 {
15     char get_name[30];
16     cout << "Enter your name :";// a word
17     cin >> get_name;
18     char * name = new char[strlen(get_name)+1];
19     strcpy(name, get_name);// do not use name = get_name
20     //because name will get get_name address it\'s in the stack
21     //it is stupid idea.
22     return name;
23 }

考虑到内存的问题记得要在new之后不用了要delete,释放内存资源。

delete [] name;

没学过C语言,照着文档用malloc-free版本的。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 using namespace std;
 5 char * getname(void);
 6 int main()
 7 {
 8     char * name;
 9     name = getname();
10     cout << "My name is : " << name << endl;
11 //    delete [] name;
12     free(name);
13     cout << "---------华丽的分割线----------" << endl;
14     return 0;
15 }
16 
17 char * getname()
18 {
19     char get_name[30];
20     cout << "Enter your name :";// read a word
21     cin >> get_name;
22     char * name = (char*)malloc(strlen(get_name)+1);
23     strcpy(name, get_name);
24     return name;
25 }

 附上文档:

free了不代表这个指针不能用了,只是释放了内存地址。 

 


附加上一个坑:

char * a = "Hello World";

a[0] = \'M\';

这个是不可以的,因为"Hello World"是字符串常量,修改常量是不允许的,应该把这段写成

const char * a = "Hello World";

这样更好的引起注意。

 

以上是关于C++ 函数中返回字符串的一个陷阱的主要内容,如果未能解决你的问题,请参考以下文章

一个函数应该返回什么可以失败?

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

C#从返回char指针的c++函数中获取字符串/字符值

《C陷阱与缺陷》读书笔记

关于c++显示调用析构函数的陷阱

java中关于字符串的陷阱