心得经验总结:折腾几天,内存检测工具写出来了

简介: 心得经验总结:次奥,折腾几天,内存检测工具写出来了

#include

#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, "\n" );

#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 + 2sizeof(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 [span style="color: rgba(0, 0, 0, 1)"> 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 + 2sizeof(g_guard) + sizeof(alloc_node) );

if( pnode )

{

pmem = (BYTE)pnode + sizeof(alloc_node) + sizeof(g_guard);

memcpy( pmem - //代码效果参考:http://www.zidongmutanji.com/bxxx/257682.html

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 [span style="color: rgba(0, 0, 0, 1)"> 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 [span style="color: rgba(0, 0, 0, 1)"> 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 [span style="color: rgba(0, 0, 0, 1)"> 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

Rust编程语言群 1036955113

java新手自学群 626070845

java/springboot/hadoop/JVM 群 4915800

Hadoop/mongodb(搭建/开发/运维)Q群481975850

GOLang Q1群:6848027

GOLang Q2群:450509103

GOLang Q3群:436173132

GOLang Q4群:141984758

GOLang Q5群:215535604

C/C++/QT群 1414577

单片机嵌入式/电子电路入门群群 306312845

MUD/LIB/交流群 391486684

Electron/koa/Nodejs/express 214737701

大前端群vue/js/ts 165150391

操作系统研发群:15375777

汇编/辅助/破解新手群:755783453

大数据 elasticsearch 群 481975850

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

相关文章
|
6月前
|
IDE Linux 开发工具
内存泄漏检测工具Valgrind:C++代码问题检测的利器(一)
内存泄漏检测工具Valgrind:C++代码问题检测的利器
1359 0
|
5月前
|
缓存 Linux
centos内存检测工具
【6月更文挑战第1天】centos内存检测工具
161 3
|
5月前
|
监控 Linux 测试技术
edac是检测什么的,和centos内存条损害检测工具
【6月更文挑战第1天】edac是检测什么的,和centos内存条损害检测工具
173 2
|
6月前
|
C++ Windows
windows下内存检测工具
windows下内存检测工具
198 0
|
6月前
|
算法 编译器 C语言
【C/C++ 实用工具】内存泄漏与堆溢出检测工具一览
【C/C++ 实用工具】内存泄漏与堆溢出检测工具一览
352 0
|
6月前
|
缓存 测试技术 开发工具
内存泄漏检测工具Valgrind:C++代码问题检测的利器(二)
内存泄漏检测工具Valgrind:C++代码问题检测的利器
163 0
|
6月前
|
XML 存储 NoSQL
内存泄漏检测工具valgrind神器
内存泄漏检测工具valgrind神器
129 0
去公司的第一天老大问我:内存泄露检测工具你知道几个?
如果应用程序的执行时间越来越长,或者操作系统的执行速度越来越慢,这可能是内存泄漏的迹象。换句话说,正在分配虚拟内存,但在不再需要时不会返回。最终应用程序或系统内存不足,应用程序异常终止。 使用Java飞行记录器调试内存泄漏 Java飞行记录器(JFR)是一个商业特性。您可以在开发人员台式机或笔记本电脑上免费使用它,也可以在测试、开发和生产环境中用于评估目的。 但是,要在生产服务器上启用JFR,必须具有商业许可证。在JDK上为其他目的使用Java任务控制(JMC)不需要商业许可证。 下面的部分展示了图并描述了如何使用Java飞行记录器调试内存泄漏。
|
Java 测试技术 C++
log4qt内存泄露问题,heob内存检测工具的使用
log4qt内存泄露问题,heob内存检测工具的使用
|
程序员
程序员技巧 —— 内存泄漏检测工具
程序员技巧 —— 内存泄漏检测工具
105 0