为什么下面的代码是错误的?
string tag = "hello"; string s = (char*)tag.c_str();
这意味着什么:storing addresses to internal storage of temporary string objects is wrong.
有人能帮忙吗?在上述转换过程中究竟发生了什么?
所示示例中引用的消息是错误的,因为tag
不是";临时字符串对象";,而是一个比指针寿命更长的变量。这也是错误的,因为指针只在调用c_str
的完整表达式中使用,所以指针不是"0";存储";以备日后使用。
对char*
的强制转换是不必要的,应该删除。此外,对c_str
的调用是不必要的。复制字符串的一种更简单的方法是:
std::string s = tag;
这是一个错误的程序,其消息是正确的:
const char* wrong = "wrong"s.c_str(); // don't do this
std::cout << wrong; // kaboom; behaviour of program is undefined
这里,正在存储临时字符串对象的内部存储器的地址,这是错误的,因为临时字符串对象立即被破坏,因此指针无效,因此毫无用处。
string tag = "hello";
使用值"hello"
初始化tag
对象。tag
到底做了什么,这不是你关心的。它做到了,这就是你(目前(需要知道的全部。
string s = (char*)tag.c_str();
首先,您要求tag
对象允许您访问其内部缓冲区,该缓冲区存储字符串数据(请参见c_str((描述(。然后更改原始返回类型(const char*
(,然后使用它初始化新的std::string
对象。
我不知道你对s
有什么打算,但以下其中一个会是更好的选择:
std::string s = tag; // s is now a copy of tag.
std::string &s = tag; // s is now a reference to tag (what you do t s will be reflected on tag).
std::string s(std::move(tag)); // contents of tag moved to s
如果出于某种原因,您需要访问隐藏在std::string
中的内存(c_str()
方法就是这样做的(,那么您绝对不应该丢弃const
。你可能认为它有效,但最好说它现在有效。
不仅将地址存储到临时字符串对象的内部存储器是错误的,而且大多数将地址存储在字符串的内部存储器也是错误的——它是临时对象这一事实只会使情况变得更糟。以下是两个原因:
- 由于对象是临时的,这意味着该地址在对象被销毁的那一刻肯定是无效的。无效的意思是它将不再指向字符串的开头。它仍然会指向某个地方,但谁知道呢
- 即使对象不是临时的,存储那个地址也是危险的。假设有人给这个字符串指定了一个新值,一个长的值。CCD_ 19的实现方式可以导致分配或重新分配。这意味着该对象现在使用不同的位置来存储其数据。旧的地方被释放,从而可以供其他人重复使用。你还拿着旧的指针,现在指向什么?谁知道呢