std :: string复制构造函数是否在最后添加空字符?

Fah*_*qui 3 c++ iostream stl function

我首先做的,

#include <iostream>
#include <string>

void foo (std::string s) {
    std::cout << s << std::endl;
}

int main () {
    char st[] = "0";
    st[1] = '[';
    std::string s (st);
    std::cout << s << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我cout使用流插入运算符发送到流对象时,它显示垃圾(猜测它是正常行为).

然后我foo通过值传递给函数进行检查.我现在正在做这样的事情.

    foo (s);

    // after calling foo () value printed by the
    // std::cout is changed. it takes care of NULL character ('\0')
    std::cout << s << std::endl;
Run Code Online (Sandbox Code Playgroud)

它不再显示垃圾0[了.为什么?

我的问题是,我foo ()按值传递了字符串.在运行主体之前运行一个复制构造函数foo ().但仍然没有意义.这个copyctor更改参数如何从main ()值传递?

提前致谢.

Joh*_*ing 10

char st[] = "0";
Run Code Online (Sandbox Code Playgroud)

流行测验:有多大st

答案:两个chars 用于"0",一个用于空终止符.

然后你去覆盖null终止符:

st[1] = '[';
Run Code Online (Sandbox Code Playgroud)

...并尝试构建一个string基于:

std::string s (st);
Run Code Online (Sandbox Code Playgroud)

string接受a 的构造函数const char*在这里被调用,它的工作方式是查找null终止符.自从你把它吹走之后,它就会超过它的结束st.运行结束会st唤起未定义的行为,这就是你看到垃圾的原因.

值得注意的是,未定义的行为意味着任何事情都可能发生.这里的"任何东西"包括"我想要发生的事情".它不一定会得到垃圾输出,或者你的程序会崩溃.试图弄清楚为什么UB以这种方式表现出来或者这是一种无理的努力.

  • @Fahad:也许第一块垃圾恰好是''\ 0'.你正在试图理解不合理的东西. (3认同)
  • @JohnDibling:我们可以根据计算机的工作原理做出合理的假设,只要我们附上免责声明,这只是猜测.但是,对于C字符串,没有太多可争论的内容. (2认同)