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

这段代码对我来说很好,但是我在其他地方看到这段代码

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

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

4

3 回答 3

3

假设类型strstd::string,则代码都不正确。

char *a=str.c_str();

无效,因为c_str()将在不强制转换的情况下返回const char*和删除const(通常const_cast)是无效的。

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

无效,因为str.length()在分配终止空字符时不计算终止空字符需要使用strcpy().

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

于 2020-08-24T14:51:33.730 回答
1

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

第一个将指针值分配str给新的 c-tpye 字符串,并从const char*(c_str() 返回类型) 隐式转换为char*,这是错误的。如果您要更改新字符串,您将面临错误。即使c_str()返回char*,更改新字符串也会对str.

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

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

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

于 2020-08-24T15:01:54.983 回答
0

可能。

考虑一下。

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

该函数返回一个指向 的内部值的指针,该指针在str函数返回时超出范围。你有一个悬空指针。未定义的行为。注意时间旅行的鼻猴。

现在考虑一下。

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

该函数返回一个有效指针,指向一个有效的以 null 结尾的 C 样式字符串。没有悬空指针。如果您忘记delete[]它,您将有内存泄漏,但这不是您所要求的。

区别在于对象生命周期之一。注意范围。

于 2020-08-24T17:27:37.550 回答