建一个网站难不难,包头建设安全协会网站,谷歌seo网站推广怎么做优化,网站备案管理系统网站文章目录 一、堆内存不足1.1 问题描述1.2 解决办法 二、内存泄露2.1 忘记Delete2.2 忘记Free2.3 串口数据接收缺少部分字符导致的内存泄露(自己的问题)问题分析 2.4 内存泄露在Cortex-M3内核会发生什么#xff1f; cJSON开源库地址#xff1a;
cJSON 一、堆内存不足
1.1 问… 文章目录 一、堆内存不足1.1 问题描述1.2 解决办法 二、内存泄露2.1 忘记Delete2.2 忘记Free2.3 串口数据接收缺少部分字符导致的内存泄露(自己的问题)问题分析 2.4 内存泄露在Cortex-M3内核会发生什么 cJSON开源库地址
cJSON 一、堆内存不足
1.1 问题描述 这是大家遇到最多的问题之一在Keil5中给STM32F103ZET6默认分配的堆大小是0x200在数据量比较大的时候容易出现内存溢出错误。如果数据量不大那么无所谓但是数据量大了就到出现堆内存爆满。 1.2 解决办法 修改堆大小找到.s文件再找到堆大小将0x200修改为0xf00这个数根据需求定。 二、内存泄露
2.1 忘记Delete 在使用cJSON_Parse()函数解析json数据后我们需要释放掉这个函数所申请的内存因为设计到json嵌套的问题所以需要使用cJSON库中的释放函数cJSON_Delete()函数 使用示例
rootcJSON_Parse(data);
if(root ! NULL)
{/*对root进行进一步解析*/cJSON_Delete(root);
}
2.2 忘记Free 在github主页可以看到这段话使用cJSON_Print()这个函数打印json数据会申请一块内存在使用完这个函数后你有义务释放掉这个函数所申请的内存。 使用示例 char *json_string cJSON_Print(item);
if (json_string)
{printf(%s\n, json_string);free(json_string);//1.5版本以上也可以使用以下函数进行释放//cJSON_free(json_string);}2.3 串口数据接收缺少部分字符导致的内存泄露(自己的问题) 由于return造成的惨痛的教训 *有问题的代码
//
//函 数 名pid_parameter_change
//功 能接收字符串格式化为JSON格式解析其中pid数据并修改对应pid结构体
//输入参数字符串指针pid结构体指针
//返 回 值0表示解析成功1表示解析错误
//
uint8_t pid_parameter_change(const char *data,PID *pid)
{cJSON *rootNULL;cJSON *kpNULL,*kiNULL,*kdNULL;float p,i,d;rootcJSON_Parse(data);if(root!NULL){/* 解析Kp */kpcJSON_GetObjectItem(root,kp);if(kp NULL) return 1;else pcJSON_GetNumberValue(kp);/* 解析Ki */kicJSON_GetObjectItem(root,ki);if(ki NULL) return 1;else icJSON_GetNumberValue(ki);/* 解析Kd */kdcJSON_GetObjectItem(root,kd);if(kd NULL) return 1;else dcJSON_GetNumberValue(kd);/* 修改PID参数 */pid-Kpp;pid-Kii;pid-Kdd;printf(%p\r\n,root);cJSON_Delete(root);rootNULL,kpNULL,kiNULL,kdNULL;return 0;}else{cJSON_Delete(root);rootNULL;return 1; //root数据JSON格式化失败}
}*修改后的代码
//
//函 数 名pid_parameter_change
//功 能接收字符串格式化为JSON格式解析其中pid数据并修改对应pid结构体
//输入参数字符串指针pid结构体指针
//返 回 值0表示解析成功1表示解析错误
//
uint8_t pid_parameter_change(const char *data,PID *pid)
{cJSON *rootNULL;cJSON *kpNULL,*kiNULL,*kdNULL;float p,i,d;if(data[0] { data[UART1_Rx_cnt-3] } ){rootcJSON_Parse(data);if(root){/* 解析Kp */kpcJSON_GetObjectItem(root,kp);if(kp NULL) { cJSON_Delete(root);return 1;}else pcJSON_GetNumberValue(kp);/* 解析Ki */kicJSON_GetObjectItem(root,ki);if(ki NULL) { cJSON_Delete(root);return 1;}else icJSON_GetNumberValue(ki);/* 解析Kd */kdcJSON_GetObjectItem(root,kd);if(kd NULL) { cJSON_Delete(root);return 1;}else dcJSON_GetNumberValue(kd);/* 修改PID参数 */pid-Kpp;pid-Kii;pid-Kdd;/*删除JSON否则可能会发送内存泄露*/cJSON_Delete(root);rootNULL,kpNULL,kiNULL,kdNULL; // 释放掉的内存指向NULL避免产生野指针return 0;}else{/*删除JSON否则可能会发送内存泄露*/cJSON_Delete(root);rootNULL;return 1; //root数据JSON格式化失败} }else{return 1;}
}问题分析 这个问题的根源是由于串口接收到的数据不全导致的同时也有我代码不严谨的问题。 在有问题的那个代码中使用cJSON_Parse()成功解析出数据使得代码进入了if语句中 if(root) 进入if语句后再次判断json对象是否有ki这个元素 这个时候出现了问题由于串口接收缺少了ki中的i这个字符使得if语句判断结果未false直接return了。 if(ki NULL) . 注意return之前我没有使用cJSON_Delete()删除root所以出现了内存泄露 写代码的时候没考虑到cJSON_Parse()成功后解析不出json对象中的元素的问题 2.4 内存泄露在Cortex-M3内核会发生什么
未完待续…