如何将本地std :: string复制到const char *?

3
const char* getString() {
  std::string myString = "Hello!";
  return myString.str().c_str();
}

我该如何使这个函数返回一个在声明它的局部作用域之外仍然有效的 const char *? 我相信我需要使用 malloc,但我不确定。


14
为什么要这样做?只需返回 std::string 并将其保留即可。需要 char const* 时使用 s.c_str()。任何解决方案都等同于重新发明 std::string - R. Martinho Fernandes
2
你确定需要返回一个 const char* 吗? - Oliver Charlesworth
2
使用strdup/strndup函数时,不要忘记在使用完返回的字符串后将其删除。 - rectummelancolique
2
@RouteMapper 你知道这个 char * 的预期寿命吗?这个 API 是否会 free 它? delete 它?是不是 你的 代码在某个时候负责销毁它?通过将 std::string 转换为 char *,你已经失去了自动寿命管理。 - Drew Dormann
3
我正在处理LLVM API中以下文件的第54行 - http://llvm.org/docs/doxygen/html/MCExternalSymbolizer_8cpp_source.html。 - RouteMapper
显示剩余17条评论
5个回答

5

我猜你需要一个静态的字符串查找表,这样SymbolLookUp才能返回c_str值。


1
我认为你是对的。也许当我找到符号时,应该将它们映射到某个永久的位置,这样它们就不会消失了。然后,我可以返回与映射对象相对应的 c_str 值。 - RouteMapper
@RouteMapper 同意。但是当然要注意不要写入包含的 std::string 或使迭代器失效的操作。 - BoBTFish
1
@BobTFish - 当然可以。我会简单地存储std::string,并且只返回它们对应的c_str值。 - RouteMapper
那么,是的,这就是(/a)解决方案。 - BoBTFish

3
看起来你正在连接的 SymbolLookup API 假设符号存储在准永久结构中,而不是即时生成。如果你的符号确实是瞬态的,你需要以某种方式使它们永久化,可以使用类似于 C 的方式:

return strdup(myString.c_str());

或者更符合 C++ 习惯的方式:

static std::vector<std::string> sStringPool;
sStringPool.push_back(myString);
return sStringPool.back().c_str();

自然地,这将导致内存无限增长,但如果您没有关于字符串生命周期的其他信息,则几乎没有其他选择。如果您想变得聪明一点,至少可以使字符串唯一:

static std::set<std::string> sStringPool;
return sStringPool.insert(sStringPool.end(), myString)->c_str();

1
strdup 在堆上分配了字符串的副本。 - microtherion

0

只需返回std::string并继续使用它。

但要小心其生命周期,例如

const char* s = getString().c_str(); doStuff(s);

会导致第二个语句失败,因为getString返回的临时字符串只在语句结束前存在。

如果您使用的API接受const char*,则以下代码将起作用:

callTheAPI(getString().c_str());

然后该字符串将一直存在,直到API返回。


无法完成。请查看 OP 上的评论。 - RouteMapper

-1

编辑:请注意,它回答了问题的陈述方式。在此编辑时,似乎问题与原始意图不符,但是在合并之前无法提供改进的答案,如果可能的话。

不要这样做。使用字符串类的整个重点是不使用malloc和其他垃圾。如果您无法向适当稳定的现有位置提供const char*,则从函数返回std::string(或与您喜欢的其他字符串类匹配的类)。


3
请参考对原帖的评论以了解为何这是不可行的。 - RouteMapper
请提供更多关于API和其要求的信息,以及一些代码示例...目前的信息太模糊了。 - Balog Pal
请查看以下链接中LLVM API的第54行:http://llvm.org/docs/doxygen/html/MCExternalSymbolizer_8cpp_source.html - RouteMapper
对我来说,这意味着该调用不应检索已存储在参数结构或外部环境中的现有内容。因此,它与您的问题完全不匹配。 - Balog Pal
该调用检索符号的const char *表示。API开发人员从未自己查找符号;他们将此留给API用户。因此,它实际上与我的问题相匹配。 - RouteMapper

-2
const char* getString() {
  std::string myString = "Hello!";
  return myString.str().c_str();
}

1) 正确的语法是 myString.c_str()

2) 该函数返回一个堆栈上的字符串,因此当您返回这样的数据时,编译器会复制它或进行一些优化

3) 请注意,它返回const char *,这意味着绑定返回值的正确方法是具有类似于const char *returnValue = getString()的语句,或者将其传递给期望const char的函数。并且因为我们将const char *分配给returnValue,根据C++规范,该数据将在函数的生命周期之后存在。因此,这意味着我们可以执行const char *str = getString(),其中getString是您的函数,并且已定义并且由getString()返回的值在函数的生命周期之后存在。

我没有看到您发布的代码中有任何必要的问题。


1
这是非常错误的。我认为你想到的是,如果你通过值返回一个 std::string,你可以将该临时对象绑定到一个 const 引用上,并延长其生命周期。 - BoBTFish
2
这会返回一个悬空指针,毫无用处。 - Balog Pal
是的,你们说得对,我实际上是在考虑字符串字面量,例如 const char *str="hello"; return str;,这些应该会一直保存在内存中,直到应用程序的生命周期结束,因为它们被放置在文本段内存中。但是对于 std::string,它所指向的 char 会被删除。我的错误。 - dchhetri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接