| Делаю на ESP32 парсинг JSON-строки, которая приходит от сервера, чтобы извлечь оттуда URL. Столкнулся с ошибкой освобождения памяти при вызове cJSON_Delete. 
  do
  {
    jroot = cJSON_Parse(src);
    if (NULL == jroot)
      break;// здесь все норм
    jurl = cJSON_GetObjectItem(jroot, "fw_url");
    if (NULL == jurl)
      break;// здесь все норм
    if(!cJSON_IsString(jurl) || NULL == jurl->valuestring)
      break;// здесь все норм, делаю копию jurl->valuestring
    strcpy(dst, jurl->valuestring);
    result = true;
  } while (false);
    if (jurl)
    cJSON_Delete(jurl);  // здесь все норм
  if (jroot)
    cJSON_Delete(jroot); // а вот тут падение программы
 В логе сообщение об ошибке: 
assert failed: 0x4038ef6a
0x4038ef6a: tlsf_free at ~/esp-idf/components/heap/heap_tlsf.c:872 (discriminator 1)
 Посмотрел в heap_tlsf.c строку 872, срабатывает вот этот assert: 
tlsf_assert(!block_is_free(block) && "block already marked as free");
 Причина оказалась в особенности реализации библиотеки cJSON. Необходимо удалять только родительский объект (в этом примере jroot), потому что удаление родительского объекта автоматически удалит дочерние объекты (в этом примере jurl). Вызов cJSON_Delete(jroot) пытался удалить дочерний объект jurl, который уже был удален, поэтому возникала ошибка. Исправление ошибки: 
  //if (jurl)
  //  cJSON_Delete(jurl);
  if (jroot)
    cJSON_Delete(jroot);
 Основное правило удаления объектов cJSON: не надо удалять дочерние объекты. [Ссылки] 1. DaveGamble / cJSON site:github.com.2. xuzd / cJSON site:gitee.com.
 |