Chinaunix首页 | 论坛 | 博客
  • 博客访问: 32211
  • 博文数量: 13
  • 博客积分: 535
  • 博客等级: 中士
  • 技术积分: 145
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-26 11:57
文章分类
文章存档

2012年(1)

2010年(12)

我的朋友

分类: C/C++

2010-09-30 17:14:10

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


#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

文件:check1.0.zip
大小:17KB
下载:下载


阅读(611) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~