我在调试错误的字符串修剪函数时遇到了这个问题,现在我想知道究竟是什么导致了这种行为。
这是一个只包含相关位的代码片段:
#include <iostream>
#include <string>
using namespace std;
void debug(string s) { cout << "Len: " << s.length() << "; Value: '" << s << "'" << endl; }
int main()
{
string str = "ABC";
debug(str);
str.erase( str.begin() + 4, str.end() ); // Magic!
debug(str):
return 0;
}
您会注意到擦除函数正在使用一个迭代器,该迭代器从字符串末尾开始。这不是我遇到问题时使用的确切输入(它有一个打破空字符串的+1),但它有类似的效果。这是输出:
Len: 3; Value: 'ABC'
Len: 4; Value: 'ABC '
当我将str.begin() + 4
更改为更像+ 10
的内容时,很明显我开始引入垃圾数据。
我的问题是:如何使用erase()函数最终使字符串更长?另外,它只是运气,还是字符串结束后的下一个字符总是空格?
答案 0 :(得分:9)
string::erase()
具有以下前提条件:
由于您的代码不适用于此,因此它表现出未定义的行为。在分析为什么它会破坏某些东西时没有太多意义 - 基本上erase()
函数假设这不是真的。
但是如果你真正好奇正在发生什么,你至少需要指定你正在使用哪个工具链(因为UB根据编译器和库的不同而变化很大)。最简单的方法是在调试器中单步调试代码,看看它在这种情况下的行为方式。
答案 1 :(得分:2)
传递无效迭代器是未定义的行为。任何事情都可能发生。
答案 2 :(得分:2)
str.erase( str.begin() + 4, str.end() ); // Magic!
这会调用未定义的行为,因为str.begin()+4
指向str.end()
以上,因为str.size()
是3
。
这意味着,任何事情都可能发生:语言和编译器都无法保证。