设计返回有效字符串的方法或函数

时间:2017-07-28 08:10:24

标签: c++

基于此条目的想法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被销毁,并且你在返回后保留的指针变得无效。

我的问题是:如果没有实际声明其他全局变量或潜在的成员函数,我应该如何设计一个没有这种行为的方法或函数?

5 个答案:

答案 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;
}