Arduinojson: Trying to preserve generated DynamicJsonDocument

Created on 3 Nov 2019  路  2Comments  路  Source: bblanchon/ArduinoJson

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 馃槗

question

All 2 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kylegordon picture kylegordon  路  6Comments

dimityrivanov picture dimityrivanov  路  5Comments

renno-bih picture renno-bih  路  5Comments

HilalAH picture HilalAH  路  3Comments

lbussy picture lbussy  路  5Comments