There are two key concepts you need to understand to use ArduinoJson:

  1. JsonObjects and JsonArrays are stored in a JsonBuffer
  2. char* are not copied

Similarly, there are two reasons to get garbage in the output:

  1. JsonBuffer is not in memory anymore
  2. The string pointed by the char* is not in memory anymore.

Example of what you should not do:

JsonObject& myFunction() {
  StaticJsonBuffer<200> jsonBuffer;
  return jsonBuffer.createObject();
}

This is wrong because it returns a reference (a pointer if you prefer) to a JsonObject that is not in memory anymore.