std::replace_copy 与 std::string 一起使用的奇怪行为
Weird behavior of std::replace_copy used with std::string
我有这个简单的代码:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string s = "1,0";
string result;
//result.resize(s.length());
replace_copy(s.begin(), s.end(), result.begin(), ',', '.');
cout << '"' << result << '"' << endl;
cout << '"' << result.c_str() << '"' << endl;
cout << result.length() << endl;
return 0;
}
此程序的控制台输出result.resize
行未注释为:
"1.0""1.0"3
-没关系,但是当注释掉带有result.resize
的行时,输出为:
"""1.0"0
-这可能会导致奇怪的错误,因为result != result.c_str()
!!!
replace_copy
(可能还有类似的模板)的这种行为是否可以被视为标准库中的错误?我找不到任何与此主题相关的内容。谢谢。
编译器: mingw32-g++ 4.7.1
你期待什么?
如果没有 resize
,字符串中没有空间容纳新字符。
无论如何,试图复制到该空间肯定会导致"奇怪"[阅读:未定义]行为。你正在破坏你的记忆。
replace_copy
复制到目标范围,这与将新元素插入目标容器不同。范围必须已经存在...
...除非您使用back_inserter
,它的功能是一种假范围,实际上在引擎盖下执行插入:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string s = "1,0";
string result;
//result.resize(s.length()); // Look, ma! No hands!
replace_copy(
s.begin(), s.end(),
std::back_inserter<std::string>(result),
',', '.'
);
cout << '"' << result << '"' << endl;
cout << '"' << result.c_str() << '"' << endl;
cout << result.length() << endl;
}
// "1.0"
// "1.0"
// 3
现场演示
警告!在现场演示中获得正确的输出并不能证明任何事情,因为未定义的行为偶尔会"看起来有效"。但是,我有 96k 代表,你可以相信我。;)
当你使用语句时
result.resize(s.length());
您创建并初始化(更准确地说是分配)包含三个值为"\0"的元素的字符串。当不使用此语句时,字符串没有 relements 并且程序的行为是未定义的。实际上,带有未注释行的代码等效于以下内容:
string s = "1,0";
string result( s.length(), ' ' );
replace_copy(s.begin(), s.end(), result.begin(), ',', '.');
如果要像注释语句一样编写,则应使用迭代器适配器std::back_insert_iterator
replace_copy(s.begin(), s.end(), std::back_inserter( result ), ',', '.');
相关文章:
- 将fold表达式与std::一起用于两个元组
- 将 std::allocate_shared 与多态资源分配器一起使用
- 将 std::set 与基于键的比较器一起使用
- 如何将AERT_Allocate与 std:vector 一起使用
- 将用户定义的类型与 std::vector 和 std::sort 一起使用
- 将图形属性与 std::unique_ptr 捆绑在一起
- 将 std::map::emplace 与返回 shared_ptr 的函数一起使用是否正确?
- 将新放置与 std::函数一起使用不起作用
- 不能将C++的"std::filesystem"库与介子构建一起使用
- 将 std::function 与模板一起使用
- 是否可以将 std::basic_ifstream 和 std::basic_ofstream 与自定义缓冲区一起使用?
- 当返回语句时,逗号运算符、大括号初始化列表和 std::unique_ptr 组合在一起
- 如何将 std::find() 与 2d std: 数组一起使用?
- boost::interprocess::file_lock 与 std::ostream 一起使用时的错误行为
- std::remove() 按预期处理文字,但不能与取消引用的迭代器一起工作
- 将 std::transform 与 std::back_inserter 一起使用是否有效?
- 为什么使用与父级声明的 std::function 在与子级一起使用时会显示错误?
- 是否已经有一个 constexpr std::bit_cast 与 g++ 一起使用
- 将 std::variant 与 gmock 1.8 对象一起使用时编译错误
- 我不能将 'fill' std::vector 构造函数与 unique_ptrs 一起使用