返回顶部

收藏

跟踪内存分配

更多

http://blog.chinaunix.net/u3/116272/showart.php?id=2342449

/*
  Name: check.h
  Copyright: free head file
  Author: hqwfreefly
  Date: 30-09-10 17:03
  Description: 检查程序中使用malloc申请的内存是否被释放,输出统计结果到_report.txt文件
               如果无法创建_report.txt则输出结果到标准错误输出设备。该头文件的使用方法
               介绍请参考当前目录下的test.c文件。 
               欢迎随时来我的空间做客: www.hi.baidu.com/hqwfreefly 
*/

#ifndef MEMCHECK_
#define MEMCHECK_
#if defined(MEMCHECK)
#include <stdio.h>
#include <stdlib.h>
#define malloc(size) mmalloc(size, __LINE__)
#define free(addr) ffree(addr, __LINE__)
#define __REPORT_FILE "_report.txt"
static void *(*pmalloc)(size_t) = malloc;
static void (*pfree)(void *) = free;
static FILE *___fp = NULL;
#define REPORT show_result()
//初始化,为双向链表的头结点分配空间,打开报告文件 

#define CHECKSTART \
    do \
    { \
        tail = head = (Mem *)pmalloc(sizeof(Mem)); \
        if(head == NULL) \
        { \
            fprintf(stderr, "Fail to init."); \
            exit(1); \
        } \
        head->next = NULL; \
        head->pre = NULL; \
            if((___fp = fopen(__REPORT_FILE, "wt")) == NULL) \
            { \
            fprintf(stderr, "+--------------------------------------------------------+\n"); \
                fprintf(stderr, "|Error: Unable to create _report.txt. Permisson denied. |\a\n"); \
            fprintf(stderr, "+--------------------------------------------------------+\n"); \
            ___fp = stderr; \
            } \
    }while(0)

//结束处理,释放链表,关闭报告文件 

#define CHECKEND \
    do{ \
        Mem *temp0 = head, *temp1 = head->next; \
        for(; temp1 != NULL; temp1 = temp1->next) \
        { \
            pfree(temp0); \
            temp0 = temp1; \
        } \
        fclose(___fp); \
        if(___fp == stderr) \
            getch(); \
    }while(0)

//内存块结构体

typedef struct Mem
{
    size_t size; //大小

    size_t addr; //地址

    size_t line; //申请行号

    int isfreed; //释放标记 1代表已经释放 0代表未释放

    struct Mem *next; //下一内存块指针

    struct Mem *pre; //上一内存块指针

}Mem;

static Mem *head = NULL; //头指针

static Mem *tail = NULL; //尾指针

//申请函数

void *mmalloc(const size_t size, const size_t line)
{
    Mem *new_node = NULL;
    Mem *temp_node = NULL;
    void *addr = NULL;

    addr = pmalloc(size);
    if((new_node = (Mem *)pmalloc(sizeof(Mem))) == 0)
    {
        fprintf(stderr, "Fail to malloc node for recording.");
        exit(1);
    }
    new_node->size = size;
    new_node->addr = (size_t)addr;
    new_node->line = line;
    new_node->isfreed = 0;
    new_node->next = NULL;
    new_node->pre = NULL;
    tail->next = new_node;
    temp_node = tail;
    tail = new_node;
    tail->pre = temp_node;

    return addr;

}

//释放函数

int ffree(void *addr, const size_t line)
{
    size_t temp_addr = (size_t)addr;
    Mem *p = head->next;

    for(; p != NULL; p = p->next)
    {
        if(p->addr == temp_addr)
        {
            p->isfreed = 1;
            pfree(addr);
            return 0;
        }
    }
    fprintf(___fp, "%s%u\n", "Try to free undistributed memory. At line: ", line);
    return -1;
}

//打印信息

void show_result(void)
{
    Mem *temp = head->next;
    size_t total_size = 0;
    size_t freed_size = 0;

    fprintf(___fp, "__________________________________________________________\n");
    fprintf(___fp, "[行号]\t\t[地址]\t\t[大小]\t\t[释放标记]\n");
    for(; temp != NULL; temp = temp->next)
    {
     fprintf(___fp, "%u\t\t0x%x\t%u\t\t%u\n", temp->line, temp->addr, temp->size, temp->isfreed);
     total_size += temp->size;
     freed_size += temp->size * temp->isfreed;
    }
    fprintf(___fp, "__________________________________________________________\n");
    fprintf(___fp, "总计申请: %-37u bytes\n总计释放: %-37u bytes\n内存溢出: %-37u bytes\n",
            total_size, freed_size, total_size - freed_size);
    fprintf(___fp, "__________________________________________________________\n");
    fprintf(___fp, "%s\t%s\n", __DATE__, __TIME__);
    fprintf(___fp, "__________________________________________________________\n");

}
#else
#define CHECKSTART
#define CHECKEND
#define REPORT
#endif
#endif

标签:c/c++

收藏

0人收藏

支持

0

反对

0

相关聚客文章
  1. yuer 发表 2018-07-27 08:46:07 coredump之百米之内必有解药
  2. hev 发表 2018-04-28 06:11:38 一个简单、轻量的 Linux 协程实现
  3. hev 发表 2017-10-19 15:56:11 FSH – 助你接入私有网络中的 Linux 终端
  4. gonwan 发表 2015-04-15 08:03:07 Database Access Layer in C++
  5. gonwan 发表 2015-12-28 08:41:13 Basic Usage of Boost MultiIndex Containers
  6. gonwan 发表 2016-01-19 03:37:54 Coroutines in C++/Boost
  7. Haoxiang Li 发表 2017-10-25 20:29:02 MXNet C++ Deployment
  8. yuer 发表 2017-10-20 07:52:47 基于leveldb的持久消息队列SDK
  9. yuer 发表 2017-10-07 07:51:32 c++11完美转发
  10. 博主 发表 2016-09-03 00:00:00 C++编译期类型信息的利用
  11. yuer 发表 2017-09-06 03:03:29 libcurl访问unix socket
  12. yuer 发表 2017-09-07 08:14:58 valgrind检测php扩展的warning

发表评论