RapidJson内存分配机制是否存在根本性缺陷相关问题咨询
问题确认
你的理解完全符合RapidJSON的内存设计逻辑,给出的示例代码确实存在非法内存访问问题:author对象持有的字符串内存由局部作用域内的document的分配器分配,document离开作用域销毁时会释放所有它管理的内存块,author后续访问的就是已经失效的内存地址。
关于是否为设计缺陷的说明
这一特性是RapidJSON刻意做的性能取舍,不属于根本性缺陷:
- 为了实现极高的JSON处理性能,RapidJSON默认没有对
Value持有的内存做引用计数、单独析构的设计,所有动态内存都由分配器统一管理、销毁时批量释放,大幅降低了内存管理的额外开销 - 你提到的
Value无法作为一等对象自由传递的问题,RapidJSON提供了对应的解决方案来适配这类需求:- 如果你需要让
Value脱离原分配器独立存在,可以调用Value::CopyFrom接口完成深拷贝,将内容复制到目标分配器管理的内存下 - 你可以不将分配器依附于
Document实例,单独创建rapidjson::MemoryPoolAllocator实例自行管理其生命周期,只要保证分配器的生命周期长于所有使用它分配内存的Value即可 - 对于固定的短字符串,你可以使用
SetString的常量字符串重载,不需要依赖动态分配的内存
- 如果你需要让
示例代码修正方案
你可以通过单独管理分配器的方式实现需求,修改后的代码如下:
#include <rapidjson/document.h> #include <rapidjson/stringbuffer.h> #include <rapidjson/writer.h> #include <iostream> int main(int argc, char* argv[]) { using namespace rapidjson; // 单独创建分配器,生命周期覆盖整个main函数 MemoryPoolAllocator<> allocator; Value author; { char buffer[10]; int len = sprintf(buffer, "%s %s", "Milo", "Yip"); author.SetString(buffer, len, allocator); } StringBuffer buffer; Writer<rapidjson::StringBuffer> writer( buffer ); author.Accept( writer ); std::cout << buffer.GetString( ) << std::endl; return 0; }
内容的提问来源于stack exchange,提问作者RobertGBJones
相关产品推荐
相关产品推荐

