我正在使用 Rapidjson 并注意到当我在 g++ (-O1/-O2/-O3) 中打开优化时,我遇到了分段错误。我想我已经追踪到了 rapidjson 中的 GenericValue& AddMember() 函数。
GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
RAPIDJSON_ASSERT(IsObject());
RAPIDJSON_ASSERT(name.IsString());
Object& o = data_.o;
if (o.size >= o.capacity) {
if (o.capacity == 0) {
o.capacity = kDefaultObjectCapacity;
o.members = reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member)));
}
else {
SizeType oldCapacity = o.capacity;
o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5
o.members = reinterpret_cast<Member*>(allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member)));
}
}
o.members[o.size].name.RawAssign(name);
o.members[o.size].value.RawAssign(value);
o.size++;
return *this;
}
调试时,我可以看到 kDefaultObjectCapacity ( 正在优化(这是一个静态的 const SizeType kDefaultObjectCapacity = 16)
因此行“o.capacity = kDefaultObjectCapacity;” 没有被执行,并且 malloc 正在分配 0 字节然后尝试强制转换它。
为什么要删除此静态常量?
我曾尝试使 Object& o 既易变又静态,但均未奏效。有任何想法吗?
谢谢威尔
编辑:我无法在嵌入式平台上轻松运行测试,rapidjson 目前是使用 buildroot 构建的。我尝试了单元测试,但无法让它们达到目标。
我可以看看提供程序集,但它是大型应用程序的一部分,因此可能很难找到合适的位。
有关信息,这是调用 rapidjson 代码的方法,这似乎是问题所在:
int16_t FrontEndJSONHandlers::get_run_cfg_packer(JSONEngine& json_engine, char *message, int32_t *length)
{
Document doc;
// Need to pack an empty request to get the data
doc.SetObject();
doc.AddMember(JSONRPC_MEMBER, JSONRPC_VERSION, doc.GetAllocator());
doc.AddMember(METHOD_MEMBER, JSON_RPC_METH_GET_RUN_CFG, doc.GetAllocator());
doc.AddMember(ID_MEMBER, json_engine.GetNextMessageID(), doc.GetAllocator());
// Format the message
json_engine.FormatMessageAndRegisterResponseHandler(&doc, &message, &length, get_run_cfg_handler);
return 0;
}
如果我将 Document doc 设为静态,它不会出现段错误 - 不确定这是否是最好的解决方法?