使用string.erase()使字符串更长?

时间:2012-02-22 17:30:16

标签: c++

我在调试错误的字符串修剪函数时遇到了这个问题,现在我想知道究竟是什么导致了这种行为。

这是一个只包含相关位的代码片段:

#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()函数最终使字符串更长?另外,它只是运气,还是字符串结束后的下一个字符总是空格?

3 个答案:

答案 0 :(得分:9)

string::erase()具有以下前提条件:

  • 要求:第一个和最后一个是* this上的有效迭代器,定义范围[first,last)

由于您的代码不适用于此,因此它表现出未定义的行为。在分析为什么它会破坏某些东西时没有太多意义 - 基本上erase()函数假设这不是真的。

但是如果你真正好奇正在发生什么,你至少需要指定你正在使用哪个工具链(因为UB根据编译器和库的不同而变化很大)。最简单的方法是在调试器中单步调试代码,看看它在这种情况下的行为方式。

答案 1 :(得分:2)

传递无效迭代器是未定义的行为。任何事情都可能发生。

答案 2 :(得分:2)

str.erase( str.begin() + 4, str.end() );  // Magic!

这会调用未定义的行为,因为str.begin()+4指向str.end()以上,因为str.size()3

这意味着,任何事情都可能发生:语言和编译器都无法保证。