如何解决mongo-cxx-driver r3.9.0中bsoncxx::to_json的段错误
问题分析与修复
段错误根本原因
你遇到的段错误是悬空视图引用导致的:
make_document返回的是bsoncxx::document::value类型,该对象持有BSON文档的内存所有权。- 你直接将其赋值给
bd::view query,此时临时创建的document::value对象会在该行代码执行结束后立即销毁,导致query视图指向已被释放的内存。 - 后续调用
bsoncxx::to_json(query)时访问无效内存,触发段错误。
修复方案
方案1:显式持有文档所有权
先保存document::value对象,再基于它获取视图,确保所有权对象在视图使用期间保持有效:
namespace bbs = bsoncxx::builder::stream; namespace bd = bsoncxx::document; using bsoncxx::builder::basic::kvp; using bsoncxx::builder::basic::make_array; using bsoncxx::builder::basic::make_document; using bbs::open_document; using bbs::close_document; using bbs::finalize; // 构建子文档时,直接获取持有所有权的value对象(更规范) auto eq_doc = bbs::document{} << kUpdatedAtField << last_read_timestamp_ << kIdField << open_document << "$gt" << last_query_id_ << close_document << finalize; auto gt_doc = bbs::document{} << kUpdatedAtField << open_document << "$gt" << last_read_timestamp_ << close_document << finalize; // 先保存顶层文档的value,再获取视图 bd::value query_value = make_document(kvp("$or", make_array(eq_doc.view(), gt_doc.view()))); bd::view query = query_value.view(); LOG(INFO) << "query generated " << bsoncxx::to_json(query);
方案2:简化写法(直接使用value对象)
document::value可以隐式转换为document::view,因此无需显式创建view,直接使用value对象即可:
auto eq_doc = bbs::document{} << kUpdatedAtField << last_read_timestamp_ << kIdField << open_document << "$gt" << last_query_id_ << close_document << finalize; auto gt_doc = bbs::document{} << kUpdatedAtField << open_document << "$gt" << last_read_timestamp_ << close_document << finalize; auto query = make_document(kvp("$or", make_array(eq_doc.view(), gt_doc.view()))); LOG(INFO) << "query generated " << bsoncxx::to_json(query);
关键注意事项
在mongo-cxx-driver中:
*::view类型是无所有权的引用,必须确保对应的*::value对象在view的生命周期内始终存在。- 避免将临时的
value对象直接赋值给view,这会导致悬空引用,引发内存错误。
内容的提问来源于stack exchange,提问作者Praneeth Vallem
相关产品推荐
相关产品推荐

