C++ '+' 连接运算符更改指针向量中指针的内容

C++ '+' concatenation operator changing contents of pointers in pointer vector

所以我想编写一个程序来执行以下操作:

现在我还声明了一个 std::vector<const char*> lines 指向 object

中的所有 \n 个字符

在我们以最后一个要点中给出的示例为例,lines 有 3 个元素指向 \n 个字符

代码如下:

#include <iostream>
#include <string>
#include <vector>
int main()
{
    std::vector<const char*> lines;
    std::string object = "\n";
    lines.push_back(object.c_str());
    std::string temp;
    int object_size;
    while (std::getline(std::cin,temp))
    {
        object_size = object.length();
        object = object + temp;
        object = object + "\n";
        lines.push_back(object.c_str() + object_size + temp.size());//pointers in this point to all the \n characters

    }

}

现在进入问题:

所以输入后

hello
name
is

并在 vs 2019 集成调试器的 watch window 中检查行和对象的值,它显示

object="\nhello\nname\nis\n"
lines[0]=0x0082fb04"\nhello\nname\nis\n"                \points to first \n
lines[1]=0x0082fb0a"\nname\nis\n"                        \points to second \n
lines[2]=0x0082fb0f"\nis\n"                               \points to third \n
lines[3]=0x0082fb12"\n"                                    \points to last \n

这是有道理的,因为 object 中有 4 个 \n

现在我在下一行输入 xyzabc,所以控制台看起来像:

hello
name
is
xyzabc

在 while 循环中,一切正常,直到行 object=object+temp;

一执行object=object+temp;,调试器就显示:

object="\nhello\nname\nis\nxyzabc"       \object does not end with \n because object = object + "\n" has not been executed yet
lines[0]=0x0082fb04 "pù\x4\x1lo\nname\nis"
lines[1]=0x0082fb0a "\nname\nis"
lines[2]=0x0082fb1f "\nis"
lines[3]=0x0082fb12""    

object 的值符合预期,但 lines 中的指针指向的内容已被 object=object+temp 行修改 执行该行后的预期值为:

object="\nhello\nname\nis\nxyzabc"
lines[0]=0x0082fb04"\nhello\nname\nis\nxyzabc"                
lines[1]=0x0082fb0a"\nname\nis\nxyzabc"                        
lines[2]=0x0082fb0f"\nis\nxyzabc"                               
lines[3]=0x0082fb12"\nxyzabc"                                    

为什么会这样?以及如何附加 I objecttemp 而不会遇到这个问题?

object + temp;object + "\n"; 都很好并且做正确的事情:连接字符串。但是,这是不正确的:

lines.push_back(object.c_str() + object_size + temp.size());

因为 (cppreference::string::c_str)...

Returns a pointer to a null-terminated character array with data equivalent to those stored in the string.

The pointer is such that the range [c_str(); c_str() + size()] is valid and the values in it correspond to the values stored in the string with an additional null character after the last position.

The pointer obtained from c_str() may be invalidated by:

  • Passing a non-const reference to the string to any standard library function, or
  • Calling non-const member functions on the string, excluding operator[], at(), front(), back(), begin(), rbegin(), end() and rend().

c_str 返回的指针不应该独立于字符串存储。如果你想在向量中存储字符串(而不是无效的指针)你应该使用 std::vector<std::string>.

object 可能会在您将内容连接到其中时重新分配。这意味着指向其在 lines 中的内容的指针无效。那是未定义的行为。