【检测内存泄漏的几种方法 C】

简介: 【检测内存泄漏的几种方法 C】
//#define __USE_GNU
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <mcheck.h>
#if 0
extern void *__libc_malloc(size_t size);
int enable_malloc_hook = 1;
extern void __libc_free(void* p);
int enable_free_hook = 1;
// func --> malloc() { __builtin_return_address(0)}
// callback --> func --> malloc() { __builtin_return_address(1)}
// main --> callback --> func --> malloc() { __builtin_return_address(2)}
//calloc, realloc
void *malloc(size_t size) {
  if (enable_malloc_hook) {
    enable_malloc_hook = 0;
    void *p = __libc_malloc(size);
    void *caller = __builtin_return_address(1); // 1
    char buff[128] = {0};
    sprintf(buff, "./mem/%p.mem", p);
    FILE *fp = fopen(buff, "w");
    fprintf(fp, "[+%p] --> addr:%p, size:%ld\n", caller, p, size);
    fflush(fp);
    //fclose(fp); //free
    enable_malloc_hook = 1;
    return p;
  } else {
    return __libc_malloc(size);
  }
  return NULL;
}
void free(void *p) {
  if (enable_free_hook) {
    enable_free_hook = 0;
    char buff[128] = {0};
    sprintf(buff, "./mem/%p.mem", p);
    if (unlink(buff) < 0) { // no exist
      printf("double free: %p\n", p);
    }
    __libc_free(p);
    // rm -rf p.mem
    enable_free_hook = 1;
  } else {
    __libc_free(p);
  }
}
#elif 0
void *malloc_hook(size_t size, const char *file, int line) {
  void *p = malloc(size);
  char buff[128] = {0};
  sprintf(buff, "./mem/%p.mem", p);
  FILE *fp = fopen(buff, "w");
  fprintf(fp, "[+%s:%d] --> addr:%p, size:%ld\n", file, line, p, size);
  fflush(fp); 
  fclose(fp);
  return p;
}
void free_hook(void *p, const char *file, int line) {
  char buff[128] = {0};
  sprintf(buff, "./mem/%p.mem", p);
  if (unlink(buff) < 0) { // no exist
    printf("double free: %p\n", p);
    return ;
  }
  free(p);
}
#if 1
#define malloc(size)  malloc_hook(size, __FILE__, __LINE__)
#define free(p)     free_hook(p, __FILE__, __LINE__)
#endif
#elif 1
typedef void *(*malloc_hook_t)(size_t size, const void *caller);
malloc_hook_t malloc_f;
typedef void (*free_hook_t)(void *p, const void *caller);
free_hook_t free_f;
int replaced = 0;
void mem_trace(void);
void mem_untrace(void);
void *malloc_hook_f(size_t size, const void *caller) {
  mem_untrace();
  void *ptr = malloc(size);
  //printf("+%p: addr[%p]\n", caller, ptr);
  char buff[128] = {0};
  sprintf(buff, "./mem/%p.mem", ptr);
  FILE *fp = fopen(buff, "w");
  fprintf(fp, "[+%p] --> addr:%p, size:%ld\n", caller, ptr, size);
  fflush(fp);
  fclose(fp); //free
  mem_trace();
  return ptr;
}
void *free_hook_f(void *p, const void *caller) {
  mem_untrace();
  //printf("-%p: addr[%p]\n", caller, p);
  char buff[128] = {0};
  sprintf(buff, "./mem/%p.mem", p);
  if (unlink(buff) < 0) { // no exist
    printf("double free: %p\n", p);
    return ;
  }
  free(p);
  mem_trace();
}
void mem_trace(void) { //mtrace
  replaced = 1;
  malloc_f = __malloc_hook; //malloc --> 
  free_f = __free_hook;
  __malloc_hook = malloc_hook_f;
  __free_hook = free_hook_f;
}
void mem_untrace(void) {
  __malloc_hook = malloc_f;
  __free_hook = free_f;
  replaced = 0;
}
#endif
/*
 @ ./memleak:[0x400645] + 0x257c450 0x14
 */
// addr2line -f -e memleak -a 0x4006f7
int main() {
#if 0
  void *p1 = malloc(10);
  void *p2 = malloc(20); //calloc, realloc
  free(p1);
  void *p3 = malloc(20);
  void *p4 = malloc(20);
  free(p2);
  free(p4);
  //free(p4);
#elif 1
  mem_trace();
  void *p1 = malloc(10);
  void *p2 = malloc(20); //calloc, realloc
  free(p1);
  void *p3 = malloc(20);
  void *p4 = malloc(20);
  free(p2);
  free(p4);
  mem_untrace();
#else
  mtrace();
  void *p1 = malloc(10);
  void *p2 = malloc(20); //calloc, realloc
  free(p1);
  void *p3 = malloc(20);
  void *p4 = malloc(20);
  free(p2);
  free(p4);
  muntrace();
#endif
  return 0;
}
相关文章
|
18天前
|
存储 安全 iOS开发
内存卡怎么格式化?6个格式化方法供你选
随着使用时间的增加,内存卡可能会因为数据积累、兼容性或是文件系统损坏等原因需要进行格式化。那么怎样正确格式化内存卡呢?格式化内存卡的时候需要注意什么呢?本文会给大家提供详细的步骤,帮助大家轻松完成格式化内存卡的操作。
|
2月前
|
监控 JavaScript Java
Node.js中内存泄漏的检测方法
检测内存泄漏需要综合运用多种方法,并结合实际的应用场景和代码特点进行分析。及时发现和解决内存泄漏问题,可以提高应用的稳定性和性能,避免潜在的风险和故障。同时,不断学习和掌握内存管理的知识,也是有效预防内存泄漏的重要途径。
200 52
|
6天前
|
存储 程序员 编译器
什么是内存泄漏?C++中如何检测和解决?
大家好,我是V哥。内存泄露是编程中的常见问题,可能导致程序崩溃。特别是在金三银四跳槽季,面试官常问此问题。本文将探讨内存泄露的定义、危害、检测方法及解决策略,帮助你掌握这一关键知识点。通过学习如何正确管理内存、使用智能指针和RAII原则,避免内存泄露,提升代码健壮性。同时,了解常见的内存泄露场景,如忘记释放内存、异常处理不当等,确保在面试中不被秒杀。最后,预祝大家新的一年工作顺利,涨薪多多!关注威哥爱编程,一起成为更好的程序员。
|
2月前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
74 6
|
2月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
62 6
|
2月前
|
Web App开发 JavaScript 前端开发
使用 Chrome 浏览器的内存分析工具来检测 JavaScript 中的内存泄漏
【10月更文挑战第25天】利用 Chrome 浏览器的内存分析工具,可以较为准确地检测 JavaScript 中的内存泄漏问题,并帮助我们找出潜在的泄漏点,以便采取相应的解决措施。
456 9
|
2月前
|
监控 JavaScript 前端开发
如何检测和解决 JavaScript 中内存泄漏问题
【10月更文挑战第25天】解决内存泄漏问题需要对代码有深入的理解和细致的排查。同时,不断优化和改进代码的结构和逻辑也是预防内存泄漏的重要措施。
83 6
|
3月前
|
机器学习/深度学习 算法 物联网
大模型进阶微调篇(一):以定制化3B模型为例,各种微调方法对比-选LoRA还是PPO,所需显存内存资源为多少?
本文介绍了两种大模型微调方法——LoRA(低秩适应)和PPO(近端策略优化)。LoRA通过引入低秩矩阵微调部分权重,适合资源受限环境,具有资源节省和训练速度快的优势,适用于监督学习和简单交互场景。PPO基于策略优化,适合需要用户交互反馈的场景,能够适应复杂反馈并动态调整策略,适用于强化学习和复杂用户交互。文章还对比了两者的资源消耗和适用数据规模,帮助读者根据具体需求选择最合适的微调策略。
1044 5
|
2月前
|
Web App开发 缓存 JavaScript
如何检测和解决闭包引起的内存泄露
闭包引起的内存泄露是JavaScript开发中常见的问题。本文介绍了闭包导致内存泄露的原因,以及如何通过工具检测和代码优化来解决这些问题。
|
3月前
|
缓存 监控 Java
在使用 Glide 加载 Gif 动画时避免内存泄漏的方法
【10月更文挑战第20天】在使用 Glide 加载 Gif 动画时,避免内存泄漏是非常重要的。通过及时取消加载请求、正确处理生命周期、使用弱引用、清理缓存和避免重复加载等方法,可以有效地避免内存泄漏问题。同时,定期进行监控和检测,确保应用的性能和稳定性。需要在实际开发中不断积累经验,根据具体情况灵活运用这些方法,以保障应用的良好运行。