首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >释放cJSON对象时cJSON内存泄漏

释放cJSON对象时cJSON内存泄漏
EN

Stack Overflow用户
提问于 2021-02-18 14:44:24
回答 1查看 492关注 0票数 0

在使用cJSON库时,我面临一个问题。我假设在一定时间(从40分钟到1小时)后会出现内存泄漏,从而破坏代码。

我复制了下面的代码:

代码语言:javascript
复制
void my_work_handler_5(struct k_work *work)
{

     char *ptr1[6];
     int y=0;
     static int counterdo = 0;
     char *desc6 = "RSRP";
     char *id6 = "dBm";
     char *type6 = "RSRP";
     char rsrp_str[100];
     snprintf(rsrp_str, sizeof(rsrp_str), "%d", rsrp_current);

     sensor5 = cJSON_CreateObject();

    cJSON_AddItemToObject(sensor5, "description", cJSON_CreateString(desc6));
    cJSON_AddItemToObject(sensor5, "Time", cJSON_CreateString(time_string));
    cJSON_AddItemToObject(sensor5, "value", cJSON_CreateNumber(rsrp_current));
    cJSON_AddItemToObject(sensor5, "unit", cJSON_CreateString(id6));
    cJSON_AddItemToObject(sensor5, "type", cJSON_CreateString(type6));

       /* print everything */
        ptr1[counterdo] = cJSON_Print(sensor5);

        printk("Counterdo value is : %d\n", counterdo);
         
        cJSON_Delete(sensor5);
        
         counterdo = counterdo + 1;
        
        if (counterdo==6){
        for(y=0;y<=counterdo;y++){
         free(ptr1[y]);
         }
         counterdo = 0;
         }

        return;
}

我读了一些关于释放内存的其他线程,并试图这样做。有人能让我知道这是否是释放分配给cJSON对象的空间的正确方法吗?

你好,阿迪尔。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-18 16:46:34

由于cJSON是一个没有依赖项的可移植库,所以最好在PC上的代码中找出一个潜在的问题:它们是在这个环境中可用的专门工具,以便于调查。我在这里假设您有一个Linux系统,一个安装了WSL或WSL2的Windows系统,或者一个Linux虚拟机,还有一个安装好的gcc。

一个最小的、独立的、可移植的代码版本可以是:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <cJSON.h>

static int rsrp_current = 1;
static char *time_string = NULL;

void
my_work_handler_5 ()
{
  char *ptr1[6];
  int y = 0;
  static int counterdo = 0;
  char *desc6 = "RSRP";
  char *id6 = "dBm";
  char *type6 = "RSRP";
  char rsrp_str[100];
  snprintf (rsrp_str, sizeof (rsrp_str), "%d", rsrp_current);

  cJSON *sensor5 = cJSON_CreateObject ();

  cJSON_AddItemToObject (sensor5, "description", cJSON_CreateString (desc6));
  cJSON_AddItemToObject (sensor5, "Time", cJSON_CreateString (time_string));
  cJSON_AddItemToObject (sensor5, "value", cJSON_CreateNumber (rsrp_current));
  cJSON_AddItemToObject (sensor5, "unit", cJSON_CreateString (id6));
  cJSON_AddItemToObject (sensor5, "type", cJSON_CreateString (type6));

  /* print everything */
  ptr1[counterdo] = cJSON_Print (sensor5);

  printf ("Counterdo value is : %d\n", counterdo);

  cJSON_Delete (sensor5);

  counterdo = counterdo + 1;

  if (counterdo == 6)
    {
      for (y = 0; y <= counterdo; y++)
    {
      free (ptr1[y]);
    }
      counterdo = 0;
    }

  return;
}

int
main (int argc, char **argv)
{
  time_t curtime;

  time (&curtime);

  for (int n = 0; n < 3 * 6; n++)
    {
      my_work_handler_5 ();
    }
}

构建过程:

代码语言:javascript
复制
wget https://github.com/DaveGamble/cJSON/archive/v1.7.14.tar.gz
tar zxf v1.7.14.tar.gz
gcc -g -O0 -IcJSON-1.7.14 -o cjson cjson.c cJSON-1.7.14/cJSON.c

在该程序上运行val研读:

代码语言:javascript
复制
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose   ./cjson

..indicates一些内存正在被释放,以前没有分配:Invalid free() / delete / delete[] / realloc()

代码语言:javascript
复制
==6747== 
==6747== HEAP SUMMARY:
==6747==     in use at exit: 0 bytes in 0 blocks
==6747==   total heap usage: 271 allocs, 274 frees, 14,614 bytes allocated
==6747== 
==6747== All heap blocks were freed -- no leaks are possible
==6747== 
==6747== ERROR SUMMARY: 21 errors from 2 contexts (suppressed: 0 from 0)
==6747== 
==6747== 3 errors in context 1 of 2:
==6747== Invalid free() / delete / delete[] / realloc()
==6747==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==6747==    by 0x1094DA: my_work_handler_5 (cjson.c:42)
==6747==    by 0x10955A: main (cjson.c:59)
==6747==  Address 0x31 is not stack'd, malloc'd or (recently) free'd
==6747== 
==6747== 
==6747== 18 errors in context 2 of 2:
==6747== Conditional jump or move depends on uninitialised value(s)
==6747==    at 0x483C9F5: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==6747==    by 0x1094DA: my_work_handler_5 (cjson.c:42)
==6747==    by 0x10955A: main (cjson.c:59)
==6747==  Uninitialised value was created by a stack allocation
==6747==    at 0x109312: my_work_handler_5 (cjson.c:11)
==6747== 
==6747== ERROR SUMMARY: 21 errors from 2 contexts (suppressed: 0 from 0)

取代:

代码语言:javascript
复制
  for (y = 0; y <= counterdo; y++)
{
  free (ptr1[y]);
}

出自:

代码语言:javascript
复制
  for (y = 0; y < counterdo; y++)
{
  free (ptr1[y]);
}

并再次执行以下任务:

代码语言:javascript
复制
==6834== 
==6834== HEAP SUMMARY:
==6834==     in use at exit: 1,095 bytes in 15 blocks
==6834==   total heap usage: 271 allocs, 256 frees, 14,614 bytes allocated
==6834== 
==6834== Searching for pointers to 15 not-freed blocks
==6834== Checked 75,000 bytes
==6834== 
==6834== 1,095 bytes in 15 blocks are definitely lost in loss record 1 of 1
==6834==    at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==6834==    by 0x10B161: print (cJSON.c:1209)
==6834==    by 0x10B25F: cJSON_Print (cJSON.c:1248)
==6834==    by 0x1094AB: my_work_handler_5 (cjson.c:30)
==6834==    by 0x10959C: main (cjson.c:59)
==6834== 
==6834== LEAK SUMMARY:
==6834==    definitely lost: 1,095 bytes in 15 blocks
==6834==    indirectly lost: 0 bytes in 0 blocks
==6834==      possibly lost: 0 bytes in 0 blocks
==6834==    still reachable: 0 bytes in 0 blocks
==6834==         suppressed: 0 bytes in 0 blocks
==6834== 
==6834== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

一些记忆肯定被泄露了。

原因是char *ptr1[6]不是静态的,因此每次调用my_work_handler_5()时都会在堆栈上创建。因此,cJSON_Print()返回的指针在两个调用之间丢失,并且对任意指针值调用free(),因为ptr1[]可能没有初始化:

代码语言:javascript
复制
char *ptr1[6] = { NULL, NULL, NULL, NULL, NULL, NULL };

由于您每6次调用一次释放内存,这将导致您怀疑的内存泄漏。

取代:

代码语言:javascript
复制
char *ptr1[6];

出自:

代码语言:javascript
复制
static char *ptr1[6];

重新编译,再运行:

代码语言:javascript
复制
==6927== 
==6927== HEAP SUMMARY:
==6927==     in use at exit: 0 bytes in 0 blocks
==6927==   total heap usage: 271 allocs, 271 frees, 14,614 bytes allocated
==6927== 
==6927== All heap blocks were freed -- no leaks are possible
==6927== 
==6927== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

修改后的程序版本现在应该适用于您的裸金属系统。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66262256

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档