std :: string []运算符与at()

时间:2018-06-04 19:41:46

标签: c++ pointers

经过几年的C#,Javascript,Web开发等,我正在重温C ++。

有一个线程,其中解释了这些之间的主要区别在于at()方法确实绑定了检查,如果提供的索引超出范围,则抛出异常。

What is the difference between string::at and string::operator[]?

然而,这似乎不能证明我遇到的以下行为是正当的,也许有人可以帮助我?

#include <iostream>
#include <string>

using namespace std;

void remodel(string & str){
    string * ps = new string(str);

    ps->at(0) = 'n';
    cout<<*ps<<endl;
    delete ps;
}

int main(){
    string str = "Hello world";
    remodel(str);
    cin.get();
    return 0;
}

输出

nello world

在上面的代码中,我使用at()方法来更改字符串的第一个字符,并且我成功地能够这样做。打印字符串确认了这一点。

使用[]运算符时会发生不同的事情:

#include <iostream>
#include <string>

using namespace std;

void remodel(string & str){
    string * ps = new string(str);
    ps[0] = 'n';
    cout<<*ps<<endl;
    delete ps;
}

int main(){
    string str = "Hello world";

    remodel(str);

    cin.get();
    return 0;
}

输出

n

在上面的代码中,在索引0上使用[]运算符会用字母'n'替换整个字符串。这在调试器中得到了证实,我可以看到从“Hello world”到“n”的完全重新分配值

只是详细说明,如果我放置一个断点使程序在执行ps [0] ='n'之前停止,那么在inspecting the variable ps上,它似乎存储了一个用于到达字符串“Hello”的地址世界”。但是,执行此行后,相同的地址只能用于到达字符串/字符“n”。

我的假设是使用[]运算符导致在指定的索引之后放置一个空字符。但我无法确认这一点。

例如,在上面的代码中使用ps [0]我试图打印ps 1,ps [2]只是为了看看会发生什么。

我输出的是输出看似空间的无尽(空)输出,或者是一堆乱码。对于我的空字符假设似乎并非如此。为了更好的衡量,我还尝试手动将空字符放在某个位置,如ps [10],但是出现了分段错误。之前分配给我的字符串的内存超出了界限!

所以,看来我需要对这个主题做一个很好的修改,有人可以解释一下吗?如果这个问题中的某些内容含糊不清或表达不好,请随时告诉我,我会尽力解决。

1 个答案:

答案 0 :(得分:3)

您的第二个程序格式错误。它根本没有使用std::string::operator[]

string * ps = new string(str);
ps[0] = 'n';

std::string不仅支持[]运算符,每个指向类型的指针也支持[]运算符。这就是C样式数组的工作方式,而这正是您在上面的代码中所做的。

ps不是string。这是一个指针。 ps[0]是一个字符串,与*ps不同。

你可能想要this代替:

#include <iostream>
#include <string>

using namespace std;

void remodel(string & str){
    string * ps = new string(str);
    (*ps)[0] = 'n';
    // or: ps->operator[](0) = 'n';
    cout<<*ps<<endl;
    delete ps;
}

int main(){
    string str = "Hello world";

    remodel(str);

    cin.get();
    return 0;
}

或者,更具惯用性,请改用this

#include <iostream>
#include <string>

using namespace std;

void remodel(string & str){
    string ps = str;
    ps[0] = 'n';
    cout<<ps<<endl;
}

int main(){
    string str = "Hello world";

    remodel(str);

    cin.get();
    return 0;
}