查看内存泄露的几种方法

文章介绍了三种内存管理方法:一是通过宏定义替换函数实现内存分配和释放的跟踪;二是利用dlsym获取malloc和free函数地址,通过hook技术监控内存操作;三是使用Valgrind工具进行内存检测,防止内存泄漏。这些方法有助于理解和调试程序的内存行为。
摘要由CSDN通过智能技术生成

 方法一:

        该方法采用宏定义替换函数,函数的实现放在上面的原因很简单,如果把宏定义放在前面,会产生递归调用,产生错误,下面就是代码的实现,该方法的局限性,适用于单文件,往往一个工程有很多文件,采用这种方法,就必须在每个文件下复制一遍。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


void *_malloc(size_t size, char *file, const char *func, int line)
{
    void *p = malloc(size);
    printf("[+mem : %s | %s | %d | %ld]\n", file, func, line, size);
    return p; 
}

void *_free(void *p, char *file,const char *func, int line)
{
    free(p);
    printf("[-mem : %s | %s | %d]\n", file, func, line);
}

#define malloc(size) _malloc(size, __FILE__, __FUNCTION__, __LINE__)
#define free(p)   _free(p, __FILE__, __FUNCTION__, __LINE__)

int main()
{
    void *p1 = malloc(10);
    void *p2 = malloc(20);

    free(p1);
}

 下图即为运行结果,可以很明显的看出,该程序,调用了两次malloc,一次free,产生了内存泄漏。

f3314866e012449ba76acd9011d16365.png

 方法二:

        这段代码是用来获取原始的mallocfree函数的指针,并保存在全局变量malloc_ffree_f中。这是为了在hook函数中能够调用原始的mallocfree函数。

在这个代码中,通过使用dlsym()函数来获取mallocfree函数的地址。dlsym()函数是动态链接库(Dynamic Linking Library)中的一个函数,它可以根据函数名字获取函数的地址。RTLD_NEXT是一个特殊的参数,它表示在下一个库中查找指定的函数。

        关于hook,它是一种技术手段,用于在程序运行时修改或替换函数的行为。在这个例子中,通过hook技术来监测和记录程序中的内存分配和释放操作。通过在mallocfree函数中插入额外的代码,可以跟踪和记录每次内存分配和释放的调用栈信息,以便进行内存泄漏的分析和调试。

通过hook技术,可以在不修改原始代码的情况下,对程序的行为进行修改和监测。这在调试和性能分析等场景中非常有用。

        需要注意的是,__builtin_return_address函数是GCC编译器提供的扩展,不是C/C++标准库的一部分。因此,它可能在其他编译器中不可用。如果需要在其他编译器中获取返回地址,可能需要使用平台特定的方法或API。        


#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

typedef void *(*malloc_t)(size_t size);
malloc_t malloc_f = NULL;

typedef void (*free_t)(void *p);
free_t free_f = NULL;

int enable_malloc_hook = 1;
int enable_free_hook = 1;

void *malloc(size_t size)
{
    if (enable_malloc_hook)
    {
        enable_malloc_hook = 0;
        void *p = malloc_f(size);
        void *caller = __builtin_return_address(0);
        printf("malloc[+%p]\n", caller); // 在终端输入addr2line -f  -e 可执行  -a +地址可以输出在哪一行
        enable_malloc_hook = 1;
        return p;
    }
}

void free(void *p)
{
    if (enable_free_hook)
    {
        enable_free_hook = 0;
        void *caller = __builtin_return_address(0);
        printf("free[-%p]\n", caller);
        free_f(p);
        enable_free_hook = 1;
    }
    else
        free_f(p);
}

void init_hook(void)
{
    if (malloc_f == NULL)
        malloc_f = dlsym(RTLD_NEXT, "malloc");
    if (free_f == NULL)
        free_f = dlsym(RTLD_NEXT, "free");
}

#define DEBUG_MEM_LEAK init_hook();

int main()
{

    DEBUG_MEM_LEAK

    void *p1 = malloc(10);
    void *p2 = malloc(20);

    free(p1);
}

8260677366264aa88072e80ef1019a5c.png

方法三:

        最简单好用的方法,使用工具valgrind进行内存检测:

945c0dcdb3104d909800d2680af3065a.png

         这里的编译选项加 -g  可以为Memcheck 工具定位内存问题时可以定位到 C/C++的具体的某行。7bddd94b646049e490e69cfab891e311.png

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值