ASAN检测stack-use-after-scope问题:包装语法+auto关键字场景分析
问题分析与解答
1. auto grammar_wrapper的实际类型
auto推导出来的是Boost Spirit Qi的表达式模板类型,这类类型并非独立的解析器实例,而是由qi::eps、你的grammar、qi::eoi通过>组合后生成的轻量级代理对象。它不存储完整的解析器副本,而是持有对所有组成部分(包括中间步骤产生的临时对象)的引用。
2. 触发stack-use-after-scope的原因
当你执行auto grammar_wrapper = qi::eps > grammar > qi::eoi;时,表达式的计算分为三步:
- 首先计算
qi::eps > grammar,生成一个临时的表达式模板对象(记为temp_expr)。 - 接着用
temp_expr和qi::eoi组合,生成最终的表达式对象并赋值给grammar_wrapper。 - 赋值语句结束后,临时对象
temp_expr会被销毁,释放其占用的栈内存。
但grammar_wrapper内部持有对temp_expr的引用,后续调用phrase_parse时,会尝试访问已经被销毁的temp_expr,这就触发了ASAN检测到的栈内存悬空引用问题。
而直接将表达式传入phrase_parse的场景中,所有临时对象都会在函数调用期间保持存活,引用始终有效,因此不会出现内存问题。
解决方法
如果需要保存组合后的解析器,不要用auto存储表达式模板,而是用qi::rule封装,它会完整拷贝所有解析器逻辑,不再依赖临时对象的引用:
// 替换YourValueType为你的解析结果类型 qi::rule<It, YourValueType(), Skipper> grammar_wrapper; grammar_wrapper = qi::eps > grammar > qi::eoi;
内容的提问来源于stack exchange,提问作者llm
相关产品推荐
相关产品推荐

