//内存泄漏之malloc替换方法

//内存泄漏之malloc替换方法
#include "stdio.h"
#include "stdlib.h"

/*文件路径名长度,可以根据需要修改*/
#define patch_len 50
struct record
{
char name[patch_len+1];
unsigned int line;
unsigned int addr;
struct record *next;
};

#define Malloc(size) malloc_ext(size,__FUNCTION__, __LINE__)
#define Free(p) free_ext(p,__FUNCTION__, __LINE__)

void * malloc_ext(size_t size,const char *name, unsigned int line);
void free_ext(void * p,const char *name, unsigned int line);

struct record * add_record(struct record *head, unsigned int addr, unsigned int line, const char *name);
int delete_record(struct record *head, unsigned int addr);
void show_record(void);

/*定义未释放内存链表头节点*/
struct record * record_list = NULL;

struct record * add_record(struct record *head, unsigned int addr, unsigned int line, const char *name)
{
struct record *m = NULL;
struct record *n = NULL;
if(head == NULL)
{
head = (struct record*)malloc(sizeof(struct record));
head->addr = addr;
head->line = line;
memcpy(head->name, name, patch_len);
head->name[patch_len] = '\0';
head->next = NULL;
return head;
}
m = head;
while(m->next != NULL)
{
m = m->next;
}

n = (struct record*)malloc(sizeof(struct record));
n->addr = addr;
n->line = line;
memcpy(n->name, name, patch_len);
n->name[patch_len] = '\0';
n->next = NULL;
m->next = n;
m = n;
return head;
}
int delete_record(struct record *head, unsigned int addr)
{
struct record *m = NULL;
struct record *n = NULL;

if(head == NULL)
{
printf("warning: have been freed before!!");
}
m = n = head;
if(head->next == NULL)
{
if(n->addr == addr)
{
free(head);
record_list = head = NULL;
}
return 1;
}
n = m->next;
while(n != NULL)
{
if(n->addr == addr)
{
m->next = n->next;
free(n);
return 1;
}
m = m->next;
n = n->next;
}
return 1;
}

void * malloc_ext(size_t size,const char *name,unsigned int line)
{
void *p = NULL;

p = malloc(size);
if(p != NULL)
{
record_list = add_record(record_list, (unsigned int)p, line, name);
}
return p;
}

void free_ext(void * p,const char *name, unsigned int line)
{
if (p == NULL)
{
printf("can\'t free a null pointer\n");
return;
}
delete_record(record_list, (unsigned int)p);
free(p);
}

/*根据各自的系统打印未释放内存链表内容,或者写入文件*/
void show_record(void)
{
struct record *p = NULL;
struct record *head = NULL;
int i = 0;

head = record_list;
if(head == NULL)
{
printf("list is enpty!\n");
return;
}
p = head;

printf("memory list without free:\n");
while(p != NULL)
{
printf("<%s,%u>Node is:%d ,addr = 0x%x\n",p->name,p->line,++i,p->addr);

p = p->next;
}
}

char *getmem(char *string,int len)
{
char *buf = NULL;

//malloc_stats();

buf = Malloc(len);
memset(buf , 0 ,len);
snprintf(buf,len,"%s",string);
Free(buf);

//malloc_stats();
return buf;
}

int main(int argc ,char *argv[])
{
int i = 0;
char welcome[64] = "hello,world!";
printf("test malloc start:\n");
for(i = 0;i<10;i++)
{
getmem(welcome,sizeof(welcome));
}
show_record();
printf("test over.\n");

return;
}

内存泄漏之malloc替换方法的更多相关文章

  1. MFC多线程内存泄漏问题&amp;解决方法

    在用visual studio进行界面编程时(如MFC),前台UI我们能够通过MFC的消息循环机制实现.而对于后台的数据处理.我们可能会用到多线程来处理. 那么对于大多数人(尤其是我这样的菜鸟),一个 ...

  2. 上Mysql com.mysql.jdbc.StatementImpl$CancelTask内存泄漏问题和解决方法

    近来在负责公司短信网关的维护及建设,随着公司业务发展对短信依赖越来越严重了,短信每天发送量也比曾经每天40多w发送量暴增到每天达到200w发送量.由于是採用Java做发送底层,压力递增情况下不可避免的 ...

  3. Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  4. android 内存泄漏,以及检测方法

    1.为什么会产生内存泄漏 当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏. 2.内 ...

  5. android中常见的内存泄漏和解决的方法

    android中的内存溢出预计大多数人在写代码的时候都出现过,事实上突然认为工作一年和工作三年的差别是什么呢.事实上干的工作或许都一样,产品汪看到的结果也都一样,那差别就是速度和质量了. 写在前面的一 ...

  6. 使用HandyJSON导致的内存泄漏问题相关解决方法

    在移动开发中,与服务器打交道是不可避免的,从服务器拿到的接口数据最终都会被我们解析成模型,现在比较常见的数据传输格式是json格式,对json格式的解析可以使用原生的解析方式,也可以使用第三方的,我们 ...

  7. 利用Java剖析工具JProfiler查找内存泄漏的方法

    本文主要介绍如何如何利用在使用JProfiler时意识到内存泄漏以及查找内存泄漏的几种方法. 工具/原料   JProfiler 方法/步骤   JProfiler的内存视图会话提供了内存使用情况的动 ...

  8. Android - 内存泄漏的情况以及解决方法

    [译]Android内存泄漏的八种可能(上) Android防止内存泄漏的八种方法(下). Static Activities 在类中定义了静态Activity变量,把当前运行的Activity实例赋 ...

  9. VC使用CRT调试功能来检测内存泄漏

    信息来源:csdn     C/C++ 编程语言的最强大功能之一便是其动态分配和释放内存,但是中国有句古话:“最大的长处也可能成为最大的弱点”,那么 C/C++ 应用程序正好印证了这句话.在 C/C+ ...

随机推荐

  1. 避免Double数据显示为科学记数

    显示现象     数据类型 实体类中为 private Double tradeAmount; Oracle数据库中为  NUMBER(19,4) 解决方式 第一种解决方式 - 无效 将Double转 ...

  2. Activiti服务类- TaskService服务类

    一共72个接口 1.创建任务(2个方法)//创建与任何流程实例无关的新任务.Task newTask();//使用用户定义的任务id创建一个新任务.Task newTask(String taskId ...

  3. MySQL 5.6 中一个重要的优化——Index Condition Pushdown,究竟push down了什么

    1        问题描述 一条SQL,在数据库中是如何执行的呢?相信很多人都会对这个问题比较感兴趣.当然,要完整描述一条SQL在数据库中的生命周期,这是一个非常巨大的问题,涵盖了SQL的词法解析.语 ...

  4. Bzoj 1086: [SCOI2005]王室联邦(分块)

    1086: [SCOI2005]王室联邦 Time Limit: 10 Sec Memory Limit: 162 MBSec Special Judge Submit: 1557 Solved: 9 ...

  5. 数据结构实验之栈与队列二:一般算术表达式转换成后缀式(SDUT 2132)

    题目链接 #include <bits/stdc++.h> using namespace std; typedef long long ll; int ok(char ch, char ...

  6. css 计算值函数

    css有一些强大的函数: 1. calc 可以混合多种单位来计算 div { font-size: calc(100vw/5 + 1rem - 100px) } 2. max.min.clamp ma ...

  7. shell 字符串分割cut

    cut 选项与参数 -d:后面接分隔字符.与-f一起使用. -f:依据-d的分隔字符将一段信息分隔数段,用-f取出第几段的意思. -c:以字符的单位取出固定字符区间 [zhang@localhost ...

  8. Redis 的几种常见使用方式

    常见使用方式 Redis 的几种常见使用方式包括: Redis 单副本 Redis 多副本(主从) Redis Sentinel(哨兵) Redis Cluster Redis 自研 各种使用方式的优 ...

  9. 表单 Flask-WTF - 使用

    1 配置 可以使用Flask-WTF来处理web表单,在使用之前要先配置下,打开config.py,编辑添加如下内容 WTF_CSRF_ENABLED = True SECRET_KEY = 'you ...

  10. 课下选做作业MyOD

    2019-2020-1 20175227 <信息安全系统设计基础> 课下选做作业MyOD 要求 复习c文件处理内容 编写myod.c 用myod XXX实现Linux下od -tx -tc ...