解析函数的问题(int to const char*)

时间:2021-05-11 10:12:07

标签: c++ c++11 move-semantics

我需要创建一个解析函数,所以我写了这个:

inline const char* parse(const int &arg)
{
     return std::to_string(arg).c_str();
}

看起来很合理 - 至少对我来说 - 但是当我尝试使用 std::cout 而不是整数值查看此函数的值时,我得到了一些随机的 ascii 字符。

所以我尝试更改函数,结果是这样的:

inline const char* parse(const int &arg)
{
     return (new std::string(std::to_string(arg)))->c_str();
}

它按预期工作,但我想知道的是为什么函数的第一种情况不能正常工作。

另外,出现了一个次要问题(可能是一个愚蠢的问题,因为我是初学者) - 如果我动态创建 std::string ,我应该用 std::move 返回函数的值吗? return std::move((new std::string(std::to_string(arg)))->c_str());

2 个答案:

答案 0 :(得分:1)

inline const char* parse(const int &arg)
{
     return std::to_string(arg).c_str();
}

函数 parse 的本地新字符串是从 std::to_string(arg) 创建的,您可以通过 c_str 获得它的内部字符串。 c_str 当然会返回 const char *,但现在这会产生一个问题。该字符串仍然是函数的本地字符串,但是在函数结束时它被销毁后,究竟返回了什么? c_str 只返回一个指向内部字符串的指针,它不会创建复印件。因此,您有一个悬空指针:它指向已释放的内存。

inline const char* parse(const int &arg)
{
     return (new std::string(std::to_string(arg)))->c_str();
}

new 在堆上创建一个字符串。在前面的示例中,在堆栈上创建了一个字符串,该字符串在函数结束后被释放,但堆不是这样工作的。您必须使用 delete 手动删除内存。这会产生另一个问题:您返回 c_str 并且它有效,因为字符串尚未释放,但是现在如何释放字符串?确实,你不能,因为没有指向它的指针,所以你造成了内存泄漏。

您返回 const char * 的原因是:

<块引用>

我需要返回 const char* 因为该函数只能用作另一个函数中的参数(参数的类型是 const char*)。

但是您仍然可以返回 std::string 并在返回值上使用 c_strputs 的示例:

#include <cstdio>
#include <string>

std::string parse(const int &arg)
{
    return std::to_string(arg);
}

int main()
{
    std::puts(parse(42).c_str());
    return 0;
}

答案 1 :(得分:0)

这在第一种情况下会调用未定义的行为。您创建了一个字符串对象,该对象的生命周期在函数返回时结束,因此您返回的指针此时也将无效。

在第二种情况下,你会造成内存泄漏,因为字符串对象永远不会被删除。

你可以做的是复制字符串,即像这样:

return strdup(str.c_str());

当然,调用者必须在完成后释放这个指针。所以主要问题是为什么你不能返回字符串对象本身,这将是安全的方法。

std::string parse(const int &arg)
{
    return std::to_string(arg);
}