zoukankan      html  css  js  c++  java
  • 次奥,折腾几天,内存检测工具写出来了

       
    #include <stdarg.h>   
       
    #include "dbg.h"   
    #undef new   
    #undef delete   
       
    #ifndef NDEBUG   
    //输出调试信息   
    void dbgout( const char* fmt, ... )   
    {   
        char str[4096];   
        va_list v;   
        va_start( v, fmt );   
        vsprintf( str, fmt, v );   
        strcat( str, "
    " );   
    #ifdef _UNIX   
        fputs( str, stderr );   
    #endif   
    #ifdef _WIN32   
        ::OutputDebugString( str );   
    #endif   
    }   
       
    struct alloc_node   
    {   
        alloc_node* lptr;   /*记录申请记录节点左子树*/   
        alloc_node* rptr;   /*记录申请记录节点右子树*/   
        size_t      len;        /*申请的长度(不包括前后的保护长度)*/   
        CPCHAR      file;   /*申请内存的代码所在文件*/   
        UINT        line;       /*申请内存代码所在的行*/   
    };   
       
    static alloc_node* g_heap = NULL;/*堆的申请记录树根节点*/   
    static alloc_node* g_vector_heap = NULL;/*vector堆的申请记录树根节点*/   
       
    // Our magic guard bytes申请内存前后加上的保护字节   
    static BYTE g_guard[] =   
    {   
        0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,   
        0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF   
    };   
    //在堆中申请一块内存(可以申请空内存n=0)   
    void* operator new( size_t n, CPCHAR file, UINT line )   
    {   
        BYTE* pmem = NULL;   
        if( !n ) n = 1;/**/   
        alloc_node* pnode = (alloc_node*)malloc( n + 2*sizeof(g_guard) + sizeof(alloc_node) );   
        if( pnode )   
        {   
            pmem = (BYTE*)pnode + sizeof(alloc_node) + sizeof(g_guard);   
            memcpy( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) );   
            memset( pmem, time(NULL), n );/*申请的数据空间会暂时存放分配时间*/   
            memcpy( pmem + n, g_guard, sizeof(g_guard) );   
       
            pnode->lptr = pnode->rptr = NULL;   
            pnode->len = n;   
            pnode->file = file;   
            pnode->line = line;   
            alloc_node** ppuplink = &g_heap;   
            alloc_node* pcur = g_heap;   
         //按照内存分配的位置将分配记录组成二叉树,把新分配的记录放入二叉树的对应位置   
            while( pcur )   
            {   
                if( pnode == pcur )   
                {   
                    dbgout( "*** FATAL: duplicate memory allocated ***" );/*重复分配内存出错*/   
                    assert( false );   
                    exit( -1 );   
                }   
                if( pnode < pcur )   
                {   
                    ppuplink = &pcur->lptr;   
                    pcur = pcur->lptr;   
                }   
                else   
                {   
                    ppuplink = &pcur->rptr;   
                    pcur = pcur->rptr;   
                }   
            }   
            *ppuplink = pnode;   
        }   
       
        return pmem;   
    }   
    //在vector请一块内存(可以申请空内存n=0)   
    void* operator new[]( size_t n, CPCHAR file, UINT line )   
    {   
        BYTE* pmem = NULL;   
        if( !n ) n = 1;   
        alloc_node* pnode = (alloc_node*)malloc( n + 2*sizeof(g_guard) + sizeof(alloc_node) );   
        if( pnode )   
        {   
            pmem = (BYTE*)pnode + sizeof(alloc_node) + sizeof(g_guard);   
            memcpy( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) );   
            memset( pmem, time(NULL), n );   
            memcpy( pmem + n, g_guard, sizeof(g_guard) );   
       
            pnode->lptr = pnode->rptr = NULL;   
            pnode->len = n;   
            pnode->file = file;   
            pnode->line = line;   
            alloc_node** ppuplink = &g_vector_heap;   
            alloc_node* pcur = g_vector_heap;   
            while( pcur )   
            {   
                if( pnode == pcur )   
                {   
                    dbgout( "*** FATAL: duplicate memory allocated ***" );   
                    assert( false );   
                    exit( -1 );   
                }   
                if( pnode < pcur )   
                {   
                    ppuplink = &pcur->lptr;   
                    pcur = pcur->lptr;   
                }   
                else   
                {   
                    ppuplink = &pcur->rptr;   
                    pcur = pcur->rptr;   
                }   
            }   
            *ppuplink = pnode;   
        }   
       
        return pmem;   
    }   
       
    void operator delete( void* p )   
    {   
        if( !p ) return;   
        if( !g_heap )   
        {   
            dbgout( "*** FATAL: delete with empty heap ***" );   
            assert( false );   
            exit( -1 );   
        }   
       
        alloc_node* pcur = g_heap;   
        alloc_node** ppuplink = &g_heap;   
        while( pcur )   
        {   
            void* pcurblk = (char*)pcur + sizeof(alloc_node) + sizeof(g_guard);   
            if( p == pcurblk )   
            {   
                BYTE* pmem = (BYTE*)p;   
             //比较申请内存的前后保护字节段是否正确   
                if( memcmp( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) ) != 0 ||   
                    memcmp( pmem + pcur->len, g_guard, sizeof(g_guard) ) != 0 )   
                {   
                    dbgout( "*** FATAL: corrupted memory at %08X", p );   
                    assert( false );   
                    exit( -1 );   
                }   
                memset( pmem, time(NULL), pcur->len );   
                if( pcur->lptr && pcur->rptr )   
                {   
                    // node has both ptrs so replace it with left child and move   
                    // right child to bottom right of left child's tree   
                    alloc_node* pend = pcur->lptr;   
                    while( pend->rptr ) pend = pend->rptr;   
                    *ppuplink = pcur->lptr;   
                    pend->rptr = pcur->rptr;   
                }   
                else   
                {   
                    // move child up   
                    *ppuplink = (pcur->lptr) ? pcur->lptr : pcur->rptr;   
                }   
                free( pcur );   
                return;   
            }   
            if( p < pcurblk )   
            {   
                ppuplink = &pcur->lptr;   
                pcur = pcur->lptr;   
            }   
            else   
            {   
                ppuplink = &pcur->rptr;   
                pcur = pcur->rptr;   
            }   
        }   
       
        dbgout( "*** FATAL: delete on unalloced memory ***" );   
        assert( false );   
        exit( -1 );   
    }   
       
    void operator delete[]( void* p )   
    {   
        if( !p ) return;   
        if( !g_vector_heap )   
        {   
            dbgout( "*** FATAL: delete with empty heap ***" );   
            assert( false );   
            exit( -1 );   
        }   
       
        alloc_node* pcur = g_vector_heap;   
        alloc_node** ppuplink = &g_vector_heap;   
        while( pcur )   
        {   
            void* pcurblk = (char*)pcur + sizeof(alloc_node) + sizeof(g_guard);   
            if( p == pcurblk )   
            {   
                BYTE* pmem = (BYTE*)p;   
                if( memcmp( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) ) != 0 ||   
                    memcmp( pmem + pcur->len, g_guard, sizeof(g_guard) ) != 0 )   
                {   
                    dbgout( "*** FATAL: corrupted memory at %08X", p );   
                    assert( false );   
                    exit( -1 );   
                }   
                memset( pmem, time(NULL), pcur->len );   
                if( pcur->lptr && pcur->rptr )   
                {   
                    // node has both ptrs so replace it with left child and move   
                    // right child to bottom right of left child's tree   
                    alloc_node* pend = pcur->lptr;   
                    while( pend->rptr ) pend = pend->rptr;   
                    *ppuplink = pcur->lptr;   
                    pend->rptr = pcur->rptr;   
                }   
                else   
                {   
                    // move child up   
                    *ppuplink = (pcur->lptr) ? pcur->lptr : pcur->rptr;   
                }   
                free( pcur );   
                return;   
            }   
            if( p < pcurblk )   
            {   
                ppuplink = &pcur->lptr;   
                pcur = pcur->lptr;   
            }   
            else   
            {   
                ppuplink = &pcur->rptr;   
                pcur = pcur->rptr;   
            }   
        }   
       
        dbgout( "*** FATAL: delete on unalloced memory ***" );   
        assert( false );   
        exit( -1 );   
    }   
       
    void* operator new( size_t n )   
    {   
        return ::operator new( n, "(unknown)", 0 );   
    }   
       
    void* operator new[]( size_t n )   
    {   
        return ::operator new[]( n, "(unknown)", 0 );   
    }   
    //在内存分配树中遍历,寻找总共分配的长度   
    static void walk_alloc_tree( alloc_node* pcur, size_t* pttl )   
    {   
        if( pcur )   
        {   
            walk_alloc_tree( pcur->lptr, pttl );   
            dbgout( "%s(%u): %u bytes at %08X", pcur->file, pcur->line,   
                    pcur->len, (char*)pcur + sizeof(alloc_node) );   
            *pttl += pcur->len;   
            walk_alloc_tree( pcur->rptr, pttl );   
        }   
    }   
    //显示堆中分配的内存记录   
    void dump_alloc_heaps( void )   
    {   
        if( g_heap || g_vector_heap )   
        {   
            size_t ttl = 0;   
            dbgout( "Memory leaks detected" );   
            dbgout( "=====================" );   
            dbgout( "" );   
       
            if( g_heap )   
            {   
                dbgout( "Scalar objects" );   
                dbgout( "--------------" );   
                walk_alloc_tree( g_heap, &ttl );   
                dbgout( "" );   
            }   
            if( g_vector_heap )   
            {   
                dbgout( "Vector objects" );   
                dbgout( "--------------" );   
                walk_alloc_tree( g_vector_heap, &ttl );   
                dbgout( "" );   
            }   
       
            dbgout( "=====================" );   
            dbgout( "Total bytes: %u", ttl );   
            dbgout( "=====================" );   
        }   
    }   
       
    #endif   
  • 相关阅读:
    c#实现串口操作 SerialPort
    ASP.NET Core 上传大文件无法接收的问题
    如何将qlv格式的腾讯视频转换为mp4格式
    C#中HttpWebRequest的GetRequestStream执行的效率太低,甚至偶尔死掉
    LGPL 与GPL的区别
    ffmpeg
    HTTP协议/RTSP协议/RTMP协议的区别
    C#写的CRC16检验算法
    VS里属性窗口中的生成操作释义
    iOS:APNS推送主要代码
  • 原文地址:https://www.cnblogs.com/cfas/p/3160802.html
Copyright © 2011-2022 走看看