将 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);
.
我的程序接受一个向量 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);
.