将 char 转换为 std::string C++ 时的未定义行为

Undefined behavior when converting char to std::string c++

我的程序接受一个向量 std::vector<std::string> vector 和一个字符 char separator 和 returns 一个字符串,所有字符串在分隔符之间加在一起。概念是:vector[0] + separator + vector[1] + separator

代码

std::string VectorToString(std::vector<std::string> vector, char separator)
{
    std::string output;
    for(std::string segment : vector)
    {  
        std::string separator_string(&separator);
        output += segment + separator_string;
    }
    return output;
}

int main()
{
    std::vector<std::string> vector = {"Hello",  "my",  "beautiful", "people"};
    std::cout << VectorToString(vector, ' ');
}

我的预期输出是 Hello my beautiful people 但是输出是:

Hello �����my �����beautiful �����people �����

我发现字符有问题,特别是它的指针:std::cout << &separator; -> �ƚ��。但是,如果我这样做:std::cout << (void*) &separator; -> 0x7ffee16d35f7。虽然我真的不知道 (void*) 是做什么的。

问题:

1.What 发生了什么?

2.Why 发生了吗?

3.How我要修复它吗?

4.How 我是否可以防止它在未来的项目中发生?

这一行

std::string separator_string(&separator);

尝试从以 0 结尾的 C 字符串构造字符串。

但是 &separator 不是以 0 结尾的,因为它取决于 separator 之后的其他内存字节是否有 0 字节(可能不是)。所以你得到了未定义的行为。

你可以做的是使用其他构造函数:

std::string separator_string(1, separator);

这个通过重复 separator 个字符 1 次来创建一个字符串。

按标准,如下:

basic_string( const CharT* s,
              const Allocator& alloc = Allocator() );

意思是:

Constructs the string with the contents initialized with a copy of the null-terminated character string pointed to by s. The length of the string is determined by the first null character. The behavior is undefined if [s, s + Traits::length(s)) is not a valid range.

因此,std::string separator_string(&separator); 导致未定义的行为,因为 separator 不是空终止的。

为防止这种情况,您可能需要使用以下重载:

basic_string( const CharT* s,
              size_type count,
              const Allocator& alloc = Allocator() );

std::string separator_string(&separator, 1); 或更简单(正如其他答案指出的那样)std::string separator_string(1, separator);.