检测内存泄漏malloc模块

来源:互联网 发布:有组织犯罪知乎 编辑:程序博客网 时间:2024/05/16 23:51

1)实际应用中,很多地方用到malloc动态申请内存,其实频繁使用应该没有什么碎片之类的影响,linux会帮我们优化,只要我们使用后正常free就ok了。

2)检测思路是每次malloc申请的时候记录一下此时申请的位置(函数名,行号),在/tmp/下建立以位置等信息命名的空文件。free时候再把相应的文件删除掉。

3)这里用到一个小技巧,每次malloc的时候多申请一点内存,用作记录内存信息头。

4)把对应的一些宏写成空宏即可。

#ifndef __COMMON_H__#define __COMMON_H__#ifdef __cplusplusextern "C" {#endif#include <stdlib.h>#include <stdio.h>#include <string.h>#include <time.h>#include <sys/time.h>#define HEAP_TEST#ifdef HEAP_TEST#define COMMON_Malloc(size) COMMON_Malloc1(size, __FUNCTION__, __LINE__)#define COMMON_Free(ptr) COMMON_Free1(ptr)#else#define COMMON_Malloc(size) malloc(size)#define COMMON_Free(ptr) free(ptr)#endifvoid* COMMON_Malloc1(int bytes, const char* func, int line);int COMMON_Free1(void* ptr);int COMMON_GetMallocSum();int COMMON_MonotonicTime(struct timeval* pTime);int COMMON_GetRealTime(struct timeval* pTime);int COMMON_IntervalTime(struct timeval* pStart, struct timeval* pEnd); // return interval time (ms)#ifdef __cplusplus}#endif#endif
#include <sys/time.h>#include <time.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include "common.h"#include "debug.h"static unsigned int malloc_sum = 0;typedef struct MEM_HEAD_S{    void* this;    const char* func;    int line;    int size;}MEM_HEAD_S;static int  COMMON_Align(int bytes){    int ret = 0;    if (bytes % 4 != 0)    {        ret = (bytes/4 + 1) * 4;    }    else    {        ret = bytes;    }    return ret;}static void COMMON_CreateOrRmFile(MEM_HEAD_S* pMem, int IsMalloc){    char path[64];    snprintf(path, sizeof(path), "/tmp/heap_%p_%s_%d_%d", pMem->this, pMem->func, pMem->line, pMem->size);    if (IsMalloc)    {        creat(path, S_IWRITE|S_IREAD|S_IEXEC);    }    else    {        remove(path);    }}void* COMMON_Malloc1(int bytes, const char* func, int line){    CHECK(bytes > 0, NULL, "invalid parameter.\n");    bytes += sizeof(MEM_HEAD_S);    int AlignSize = COMMON_Align(bytes);    MEM_HEAD_S* ret = (MEM_HEAD_S*)malloc(AlignSize);    if (NULL != ret)    {        ret->this = ret;        ret->func = func;        ret->line = line;        ret->size = AlignSize;        COMMON_CreateOrRmFile(ret, 1);        malloc_sum += ret->size;        ret += 1;        //DBG("malloc %d ok, total malloc %d\n", AlignSize, malloc_sum);    }    else    {        ERR("malloc error.size: %d\n", AlignSize);    }    return (void*)ret;}int COMMON_Free1(void* ptr){    CHECK(NULL != ptr, -1, "invalid parameter.\n");    MEM_HEAD_S* tmp = (MEM_HEAD_S*)ptr;    tmp -= 1;    COMMON_CreateOrRmFile(tmp, 0);    malloc_sum -= tmp->size;    //DBG("free %d ok, total malloc %d\n", *tmp, malloc_sum);    free(tmp);    return 0;}int COMMON_GetMallocSum(){    return malloc_sum;}static int COMMON_clock_gettime(clockid_t clk_id, struct timeval* pTime){    struct timespec stTime;    memset(&stTime, 0, sizeof(struct timespec));    memset(pTime, 0, sizeof(struct timeval));    if (-1 == clock_gettime(clk_id, &stTime))    {        ERR("get clock time failed.\n");        return -1;    }    pTime->tv_sec = stTime.tv_sec;    pTime->tv_usec = stTime.tv_nsec/1000;    return 0;}int COMMON_MonotonicTime(struct timeval* pTime){    CHECK(NULL != pTime, -1, "invalid parameter.\n");    return COMMON_clock_gettime(CLOCK_MONOTONIC, pTime);}int COMMON_GetRealTime(struct timeval* pTime){    CHECK(NULL != pTime, -1, "invalid parameter.\n");    return COMMON_clock_gettime(CLOCK_REALTIME, pTime);}//单位毫秒int COMMON_IntervalTime(struct timeval* pStart, struct timeval* pEnd){    CHECK(NULL != pStart, -1, "invalid parameter.\n");    int IntervalTime = (pEnd->tv_sec -pStart->tv_sec)*1000 + (pEnd->tv_usec - pStart->tv_usec)/1000;    return IntervalTime;}
0 0