这段代码中是否存在悬空指针问题?

Is there a dangling pointer problem in this code?

string str;    
char *a=str.c_str();

这段代码对我来说工作正常,但我在其他任何地方都看到了这段代码

string str;
char *a=new char[str.length()];
strcpy(a,str.c_str());

我想知道哪一个是正确的,为什么?

假设str的类型是std::string,这两个代码都不正确。

char *a=str.c_str();

无效,因为 c_str() 将 return const char* 并且删除 const 而不强制转换(通常 const_cast)是无效的。

char *a=new char[str.length()];
strcpy(a,str.c_str());

无效,因为 str.length() 不计算终止 null-character 而分配终止 null-character 需要使用 strcpy().

此处发布的代码中没有悬挂指针问题,因为此处没有使指针失效。

这两个代码段做不同的事情。

首先将 str 指针值 分配给新的 c-tpye 字符串,并从 const char*(c_str() return type) 到 char*,这是错误的。如果您要更改新字符串,您将面临错误。即使 c_str() returned char*,更改新字符串也会对 str.

进行更改

另一方面,第二个从原始字符串创建一个新的 c-type 字符串,将其复制 byte-by-byte 到为新字符串分配的新内存中。 尽管您编写的代码行不正确,因为它没有涵盖 c-type 字符串 [=17=] 的终止空字符。为了解决这个问题,为其分配 1 个额外字节:

char *a=new char[str.length()+1];

将数据从第一个字符串复制到新字符串后,对其进行更改不会导致原始字符串发生变化str

可能。

考虑一下。

char const* get_string() {
    string str{"Hello"};    
    return str.c_str();
}

那个函数 returns 指向 str 的内部值的指针,它在函数 returns 时超出范围。你有一个悬垂的指针。未定义的行为。当心 time-travelling 鼻猴。

现在考虑这个。

char const* get_string() {
    string str{"Hello"};
    char const* a = new char[str.length()+1];
    strcpy(a, str.c_str());
    return a;
}

该函数 returns 指向有效 null-terminated C-style 字符串的有效指针。没有悬挂指针。如果您忘记 delete[] 它将发生内存泄漏,但这不是您所询问的。

不同之处在于对象的生命周期。注意范围。