将 << 运算符与 stringsteam 和 write 成员函数一起使用的区别
Difference between using << operator with stringsteam and write member function
我观察到,当 uint8_t
类型的缓冲区(不保证以 null 终止)被读入 stringstream
时,<<
运算符使用 ss << buff.data
,并将包含的 std::string
返回给 Python,Python 抛出错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte
但是,如果我使用 ss.write(buff.data, buff.size)
,问题就不存在了。
我假设这个问题是因为在使用<<
时,缓冲区溢出,ss
中的数据可能不再是UTF-8了。但是当我做write()
时,我定义了大小,所以没有垃圾数据的可能性。
令人惊讶的是,如果我这样做 ss.write(buff.data, buff.size + 1)
,我总是观察到一个段错误。所以我无法弄清楚 <<
是如何导致缓冲区溢出的?这两者的工作方式之间是否存在根本区别,因此当它进行非法缓冲区访问时,一个会触发段错误,而另一个则不会?或者,<<
只是走运吗?
uint8_t
是 unsigned char
的别名。当 operator<<
被赋予一个 unsigned char*
指针时,它被视为一个空终止字符串,与 char*
指针相同。因此,如果您的数据实际上不是以 null 结尾的字符串,使用 operator<<
将其写入流是 未定义的行为 。代码 可能 崩溃。它可能 将垃圾写入流。无从得知。
write()
不关心空终止符。它写入的字节数与您指定的字节数完全相同。这就是为什么使用 write()
而不是 operator<<
.
时没有任何问题的原因
我观察到,当 uint8_t
类型的缓冲区(不保证以 null 终止)被读入 stringstream
时,<<
运算符使用 ss << buff.data
,并将包含的 std::string
返回给 Python,Python 抛出错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte
但是,如果我使用 ss.write(buff.data, buff.size)
,问题就不存在了。
我假设这个问题是因为在使用<<
时,缓冲区溢出,ss
中的数据可能不再是UTF-8了。但是当我做write()
时,我定义了大小,所以没有垃圾数据的可能性。
令人惊讶的是,如果我这样做 ss.write(buff.data, buff.size + 1)
,我总是观察到一个段错误。所以我无法弄清楚 <<
是如何导致缓冲区溢出的?这两者的工作方式之间是否存在根本区别,因此当它进行非法缓冲区访问时,一个会触发段错误,而另一个则不会?或者,<<
只是走运吗?
uint8_t
是 unsigned char
的别名。当 operator<<
被赋予一个 unsigned char*
指针时,它被视为一个空终止字符串,与 char*
指针相同。因此,如果您的数据实际上不是以 null 结尾的字符串,使用 operator<<
将其写入流是 未定义的行为 。代码 可能 崩溃。它可能 将垃圾写入流。无从得知。
write()
不关心空终止符。它写入的字节数与您指定的字节数完全相同。这就是为什么使用 write()
而不是 operator<<
.