在 C++ Primer 第五版中,它说:
c_str 返回的数组不保证无限期有效。
于是我做了一个测试:
// c_str exploration
std::string strTest = "This is a test";
const char* s1 = strTest.c_str();
strTest = "This is b test";
std::cout << s1 << std::endl;
Run Code Online (Sandbox Code Playgroud)
由于 s1 是一个指针,因此它肯定会显示新值。但是,当我将值更改为不同长度的字符串时,它通常会显示一些垃圾:
// c_str exploration
std::string strTest = "This is a test";
const char* s1 = strTest.c_str();
strTest = "This is b testsssssssssssssssssssssssssss";
std::cout << s1 << std::endl;
Run Code Online (Sandbox Code Playgroud)
我认为这是因为返回的 C String 已经固定了结束空字符的位置,所以当长度改变时,它会使所有内容无效。令我惊讶的是,有时即使我将字符串更改为新长度,它仍然有效:
// c_str exploration
std::string strTest = "This is a test";
const char* s1 = strTest.c_str();
strTest = "This is b tests"; // Note the extra s at the end
std::cout << s1 << std::endl;
Run Code Online (Sandbox Code Playgroud)
第二个问题:
我也不确定为什么std::cout << s1打印内容而不是 C 字符串的地址。虽然以下代码按我的预期打印了整数的地址:
int dim = 42;
int* pdim = &dim;
std::cout << pdim << std::endl;
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,打印出字符“T”:
std::cout << *s1 << std::endl;
Run Code Online (Sandbox Code Playgroud)
我的假设是 std::cout 会自动转换,但请更多地讲授我这一点。
std::c_str()如果字符串未被修改,则返回的指针保持有效。来自cppreference.com:
通过以下方式获得的指针
c_str()可能会失效:
- 将对字符串的非常量引用传递给任何标准库函数,或者
- 对字符串调用非常量成员函数,不包括
operator[]、at()、front()、back()、begin()、rbegin()和end()。rend()
在您发布的代码中,
std::string strTest = "This is a test";
const char* s1 = strTest.c_str();
strTest = "This is b tests"; // This line makes the pointer invalid.
Run Code Online (Sandbox Code Playgroud)
然后使用指针访问字符串是未定义的行为。
std::cout << s1 << std::endl; // Undefined behavior.
Run Code Online (Sandbox Code Playgroud)
之后,尝试理解代码的作用是毫无意义的。
标准库提供了 之间的运算符重载函数std::ostream,char const*因此可以以合理的方式打印 C 样式字符串。当您使用:
std::cout << "Hello, World.";
Run Code Online (Sandbox Code Playgroud)
您希望看到Hello, World.的是输出,而不是指向该字符串的指针的值。
由于超出本答案范围的原因,该函数重载被实现为非成员函数。
template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
const CharT* s );
Run Code Online (Sandbox Code Playgroud)
替换所有与模板相关的标记后,该行将转换为:
std::ostream& operator<<(std::ostream& os, const char* s );
Run Code Online (Sandbox Code Playgroud)
您可以在cppreference.com上查看非成员重载函数的列表。
| 归档时间: |
|
| 查看次数: |
642 次 |
| 最近记录: |