-1

为什么下面的代码是错误的?

string tag = "hello"; string s = (char*)tag.c_str();

这是什么意思:storing addresses to internal storage of temporary string objects is wrong. 有人可以帮忙吗?在上述转换过程中究竟发生了什么?

4

2 回答 2

2

对于所示示例,引用的消息是错误的,因为tag它不是“临时字符串对象”,而是一个生命周期比指针更长的变量。这也是错误的,因为指针仅在c_str被调用的完整表达式中使用,因此指针不会被“存储”以备后用。

强制转换char*为不必要的,应该删除。此外,调用 to 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

这里存储的是临时字符串对象的内部存储地址,这是错误的,因为临时字符串对象立即被销毁,因此指针无效,因此无用。

于 2020-12-03T11:09:02.793 回答
-2

string tag = "hello";

tag用 的值初始化对象"hello"。究竟 hostag这样做不是你关心的问题。它做到了,这就是你需要知道的(现在)。

string s = (char*)tag.c_str();

首先,您要求tagobject 允许您访问其存储字符串数据的内部缓冲区(请参阅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. 您可能认为它有效,但最好说它现在有效

不仅将地址存储到临时字符串对象的内部存储是错误的,而且大多数情况下将地址存储到字符串的内部存储也是错误的——它是一个临时对象的事实只会让情况变得更糟。这里有两个原因:

  1. 由于对象是临时的,这意味着该地址在对象被销毁的那一刻肯定是无效的。无效是指它将不再指向字符串的开头。它仍然会指向某个地方,但谁知道那会是什么。
  2. 即使对象不是临时的,存储该地址也是危险的。假设有人为该字符串分配了一个新值,很长。实现的方式std::string可能导致分配或重新分配。这意味着对象现在使用不同的位置来存储其数据。旧的地方被释放,因此可供其他人重用。你还拿着现在指向什么的旧指针?谁知道!
于 2020-12-03T11:15:32.890 回答