Boost Tokenizer起始位置出现异常符号问题排查
C++代码使用Boost Tokenizer出现乱码问题分析
原代码
#include <iostream> #include <optional> #include <string> #include <boost/tokenizer.hpp> int main() { std::string a("http://website/some-path/,file1,file2"); char *ptr = (char *)a.c_str(); boost::char_separator<char> delim(","); std::vector<std::string> pths{}; boost::tokenizer<boost::char_separator<char>> tokens( std::string(ptr), delim); std::optional<std::string> pref = std::nullopt; for (const auto& tok : tokens) { if (!pref) { pref = tok; std::cerr << "prfix is set: " << tok << std::endl; continue; } pths.push_back(*pref + tok); } for(auto &t : pths) { std::cout << t << std::endl; } }
运行输出
prfix is set: �site/some-path/ �site/some-path/file1 �site/some-path/file2
问题描述
上述代码运行后出现乱码,但使用std::regex实现相同逻辑时输出正常。实际场景中字符串是以char*类型传入函数的,因此采用了上述写法,请问代码存在什么问题?
问题原因及修复
核心问题
问题出在临时字符串的生命周期失效导致的未定义行为:
- 构造
boost::tokenizer时传入的std::string(ptr)是一个临时对象,这个对象在tokenizer构造完成后会立刻被销毁。 boost::tokenizer不会拷贝传入的字符串,它仅保存指向原字符串数据的迭代器。当临时字符串销毁后,对应的内存空间会被释放或覆盖,后续遍历tokens时访问的就是无效内存,最终出现乱码。
修复方案
确保tokenizer使用期间,传入的字符串对象始终有效:
- 如果是
char*传入的场景,先将其转为持久化的std::string对象,再传递给tokenizer:
// 假设函数参数为char* input char* input = ...; std::string str_input(input); // 持久化字符串,生命周期覆盖tokenizer的使用过程 boost::char_separator<char> delim(","); boost::tokenizer<boost::char_separator<char>> tokens(str_input, delim);
- 修改原代码的话,直接用原字符串
a代替临时字符串即可:
// 替换原代码中tokenizer的构造参数 boost::tokenizer<boost::char_separator<char>> tokens(a, delim);
这样就能避免访问无效内存,解决乱码问题。
内容的提问来源于stack exchange,提问作者Ilonpilaaja
相关产品推荐
相关产品推荐

