c语言查内存泄露,关于c:C语言内存泄露很严重如何应对

摘要:通过介绍内存透露问题原理及检视办法,心愿后续可能从编码检视环节就杜绝内存透露导致的网上问题产生。

1. 前言

最近部门不同产品接连呈现内存透露导致的网上问题,具体表现为单板在现网运行数月当前,因为内存耗尽而导致单板复位景象。一方面,内存透露问题属于低级谬误,此类问题脱漏到现网,影响很坏;另一方面,因为内存透露问题很可能导致单板运行固定工夫当前就复位,只能通过批量降级能力解决,理论影响也很顽劣。同时,接连呈现此类问题,尤其是其中一例问题还是咱们老员工批改引入,阐明咱们不少员工对内存透露问题意识还是不够粗浅的。本文通过介绍内存透露问题原理及检视办法,心愿后续可能从编码检视环节就杜绝此类问题产生。

阐明:预防内存透露问题有多种办法,如增强代码检视、工具检测和内存测试等,本文汇集于开发人员能力晋升方面。

2. 内存透露问题原理

2.1堆内存在C代码中的存储形式

内存透露问题只有在应用堆内存的时候才会呈现,栈内存不存在内存透露问题,因为栈内存会主动调配和开释。C代码中堆内存的申请函数是malloc,常见的内存申请代码如下:

char *info = NULL; /**转换后的字符串**/

info = (char*)malloc(NB_MEM_SPD_INFO_MAX_SIZE);

if( NULL == info)

{

(void)tdm_error("malloc error!\n");

return NB_SA_ERR_HPI_OUT_OF_MEMORY;

}

因为malloc函数返回的实际上是一个内存地址,所以保留堆内存的变量肯定是一个指针(除非代码编写极其不标准)。再反复一遍,保留堆内存的变量肯定是一个指针,这对本文宗旨的了解很重要。当然,这个指针能够是单指针,也能够是多重指针。

malloc函数有很多变种或封装,如g_malloc、g_malloc0、VOS_Malloc等,这些函数最终都会调用malloc函数。

2.2堆内存的获取办法

看到本大节题目,可能有些同学有纳闷,上一大节中的malloc函数,不就是堆内存的获取办法吗?确实是,通过malloc函数申请是最间接的获取办法,如果只晓得这种堆内存获取办法,就容易掉到坑里了。个别的来讲,堆内存有如下两种获取办法:

办法一:将函数返回值间接赋给指针,个别表现形式如下:

char *local_pointer_xx = NULL;

local_pointer_xx = (char*)function_xx(para_xx, …);

该类波及到内存申请的函数,返回值个别都指针类型,例如:

GSList* g_slist_append (GSList *list, gpointer data)

办法二:将指针地址作为函数返回参数,通过返回参数保留堆内存地址,个别表现形式如下:

int ret;

char *local_pointer_xx = NULL; /**转换后的字符串**/

ret = (char*)function_xx(..., &local_pointer_xx, ...);

该类波及到内存申请的函数,个别都有一个入参是双重指针,例如:

__STDIO_INLINE _IO_ssize_t

getline (char **__lineptr, size_t *__n, FILE *__stream)

后面说通过malloc申请内存,就属于办法一的一个具体表现形式。其实这两类办法的实质是一样的,都是函数外部间接申请了内存,只是传递内存的办法不一样,办法一通过返回值传递内存指针,办法二通过参数传递内存指针。

2.3内存透露三要素

最常见的内存透露问题,蕴含以下三个因素:

因素一:函数内有部分指针变量定义;

因素二:对该部分指针有通过上一大节中“两种堆内存获取办法”之一获取内存;

因素三:在函数返回前(含失常分支和异样分支)未开释该内存,也未保留到其它全局变量或返回给上一级函数。

2.4内存开释误区

略微应用过C语言编写代码的人,都应该晓得堆内存申请之后是须要开释的。但为何还这么容易呈现内存透露问题呢?一方面,是开发人员经验不足、意识不到位或一时忽略导致;另一方面,是内存开释误区导致。很多开发人员,认为要开释的内存应该局限于以下两种:

1)间接应用内存申请函数申请进去的内存,如malloc、g_malloc等;

2)该开发人员相熟的接口中,存在内存申请的状况,如iBMC的兄弟,都应该晓得调用如下接口须要开释list指向的内存:

dfl_get_object_list(const char* class_name, GSList **list)

依照以上思维编写代码,一旦遇到不相熟的接口中须要开释内存的问题,就齐全没有开释内存的意识,内存透露问题就天然产生了。

3. 内存透露问题检视办法

检视内存透露问题,要害还是要养成良好的编码检视习惯。与内存透露三要素对应,需

要做到如下三点:

(1)在函数中看到有部分指针,就要警觉内存透露问题,养成进一步排查的习惯

(2)剖析对部分指针的赋值操作,是否属于后面所说的“两种堆内存获取办法”之一,如果是,就要剖析函数返回的指针到底指向啥?是全局数据、静态数据还是堆内存?对于不相熟的接口,要找到对应的接口文档或源代码剖析;又或者看看代码中其它中央对该接口的援用,是否进行了内存开释;

(3)如果确认对部分指针存在内存申请操作,就须要剖析该内存的去向,是会被保留在全局变量吗?又或者会被作为函数返回值吗?如果都不是,就须要排查函数所有有”return“的中央,保障内存被正确开释。

点击关注,第一工夫理解华为云陈腐技术~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值