基于此条目的想法Is it a good idea to return “ const char * ” from a function?
我想用另一个问题来解决这个问题。
请考虑以下代码:
#include <string>
#include <cstdio>
const char * GetSomeString()
{
std::string somestlstring;
somestlstring = "Hello World!";
return somestlstring.c_str();
}
int main()
{
const char * tmp = GetSomeString();
printf("%s\n", tmp);
return 0;
}
如果我用
构建它g++ source.cpp -o executable
并执行它,我显示奇怪的符号。这是因为somestlstring通过callstack被销毁,并且你在返回后保留的指针变得无效。
我的问题是:如果没有实际声明其他全局变量或潜在的成员函数,我应该如何设计一个没有这种行为的方法或函数?
答案 0 :(得分:15)
你应该放弃整个C心态并开始编写C ++:
#include <string>
#include <iostream>
std::string GetSomeString()
{
std::string somestlstring;
somestlstring = "Hello World!";
return somestlstring;
}
int main()
{
std::string tmp = GetSomeString();
std::cout << tmp << std::endl;
return 0;
}
答案 1 :(得分:4)
一个明显的解决方案是返回类型std::string
。
答案 2 :(得分:3)
如果没有实际声明其他全局变量或潜在的成员函数,我应该如何设计一个没有这种行为的方法或函数?
完全没有。如果你返回一个const char *
,你的函数会告诉调用者“这里你有一个C字符串要使用,但它仍然是我的”*),这意味着调用者不必费心去释放资源, 例如。所以你可以从实例方法(返回指向字段的指针)执行此操作,或者可以让函数返回指向某个静态缓冲区(全局变量)的指针。
如果要从函数返回动态分配的C字符串,则必须返回char *
,调用者使用它时必须free()
。
所有人都说,在C ++中这没有多大意义,除非以某种方式与C代码接口。如果你想编写C ++代码,请使用nvoigt的答案。
*)这是考虑所有权,这对处理手动管理的资源非常有帮助。某物的所有者负责适当的清理。如果不将对象的所有权转移给调用者,则只能返回const
原始指针。
答案 3 :(得分:2)
您当前正在引用本地std::string
对象的内存,该对象在对象超出范围时(从函数返回时)被销毁
如果确实想要返回const char *
:
std::string
static
(但您的应用只能共享1个值)free
它或者你得到内存泄漏,就像使用旧的str()
方法发生了很多事情一样。旧的strstream
对象,后来转换为std::string
)但正如其他人所说的那样,最好坚持使用C ++ std::string
(或const引用)作为返回值,并在C风格接口需要时获取该返回字符串的c_str()
。
std::string tmp = GetSomeString();
FILE *f = fopen(tmp.c_str(),"r");
答案 4 :(得分:0)
从函数返回后,GetSomeString()
函数中的本地字符串变量将超出范围。您将打印位于字符串之前的内存位置的随机内容。试试这个:
#include <string>
#include <cstdio>
void GetSomeString(std::string& str)
{
str = "Hello World!";
}
int main()
{
std::string str;
GetSomeString(str);
std::cout << str << std::endl;
return 0;
}