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()
将在不强制转换的情况下返回const char*
和删除const
(通常const_cast
)是无效的。
char *a=new char[str.length()];
strcpy(a,str.c_str());
无效,因为str.length()
在分配终止空字符时不计算终止空字符需要使用strcpy()
.
此处发布的代码中没有悬空指针问题,因为此处没有指针无效。
这两个代码段做不同的事情。
第一个将指针值分配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
.
可能。
考虑一下。
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[]
它,您将有内存泄漏,但这不是您所要求的。
区别在于对象生命周期之一。注意范围。