C++ stringstream中<<运算符与write成员函数的使用差异
核心问题解答
两种写入接口的行为差异
std::stringstream的<<运算符处理C风格字符串时,默认逻辑是从传入的指针地址开始向后读取,直到碰到\0终止符才停止,不会感知你原始缓冲区的实际长度。你传入的uint8_t缓冲区没有保证\0终止,因此<<会读取缓冲区后的额外内存数据,这些随机垃圾数据不符合UTF-8编码规则,返回给Python解码时就会抛出UnicodeDecodeError。ss.write(buff.data, buff.size)是严格按照你传入的长度写入,只会读取缓冲区范围内的有效数据,不会引入额外垃圾内容,因此解码正常。
越界访问未触发段错误的原因
段错误的触发有严格条件:只有当程序访问了进程未分配的内存页、或者访问了无对应权限的内存页时才会触发,并不是所有越界访问都会立即触发崩溃:
- 你调用
ss.write(buff.data, buff.size + 1)时,刚好多访问的1字节落在了进程未映射的内存地址上,因此直接触发段错误。 - 使用
<<运算符时,多读取的字节刚好仍处于进程已分配的合法内存页范围内(比如缓冲区后方是同栈帧的其他变量内存、或堆上同一块分配块的未使用区域),只要没有越过内存页边界访问未映射地址,操作系统就不会抛出段错误,只会读到脏数据。
这一现象完全是运行时内存布局的巧合,和两个接口的底层实现没有本质差异,两种越界访问都属于C++标准定义的未定义行为,随时可能出现崩溃、数据异常等问题。
内容的提问来源于stack exchange,提问作者yashC
相关产品推荐
相关产品推荐

