Hi,
I have a method that generates a JSON array:
DynamicJsonDocument collectPatternNames() {
int size = sizeof(patterns)/sizeof(*patterns);
const size_t capacity = JSON_ARRAY_SIZE(size);
DynamicJsonDocument jsonArray(capacity);
for (int i = 0; i < size; i++) {
jsonArray.add(patterns[i]->name);
}
return jsonArray;
}
I know about heap fragmentation problems, so I want to generate a DynamicJsonDocument jsonArray(capacity); only once the following way:
DynamicJsonDocument* patternNamesArray = NULL;
DynamicJsonDocument collectPatternNames() {
if (!patternNamesArray) {
int size = sizeof(patterns)/sizeof(*patterns);
const size_t capacity = JSON_ARRAY_SIZE(size);
DynamicJsonDocument jsonArray(capacity);
for (int i = 0; i < size; i++) {
jsonArray.add(patterns[i]->name);
}
patternNamesArray = &jsonArray;
}
return *patternNamesArray;
}
i.e. populate jsonArray only once and then preserve the result under patternNamesArray pointer, and keep returning it if a method is executed again (kind of like lazy init approach).
But it seems like after the first run of collectPatternNames() method my DynamicJsonDocument obj deallocates, and then all I see is NULL under patternNamesArray address.
I was thinking of implementing a custom allocator that would not call free(p), but then I use DynamicJsonDocument in other places, and seems like if I do
typedef BasicJsonDocument<DefaultAllocator> DynamicJsonDocument;
then it will apply to DynamicJsonDocument universally affecting other parts of my code where I use that.
I'm sure there is a very simple solution, but I don't work with C/C++ that often to know that haha 馃槗
Try this:
DynamicJsonDocument* patternNamesArray = nullptr;
DynamicJsonDocument& collectPatternNames() {
if (patternNamesArray == nullptr) {
int size = sizeof(patterns) / sizeof(*patterns);
const size_t capacity = JSON_ARRAY_SIZE(size);
patternNamesArray = new DynamicJsonDocument(capacity);
for (int i = 0; i < size; i++) {
patternNamesArray->add(patterns[i]->name);
}
}
return *patternNamesArray;
}
p.s. remember to delete patternNamesArray when finished.
Hi @yeralin,
You can keep the first implementation and assign the result to the global variable:
DynamicJsonDocument patternNamesArray = collectPatternNames();
Best Regards,
Benoit