📄 ps_mem.c
字号:
#include <stdio.h>
#include "ps_mem.h"
#ifdef PS_DEBUG_MEMORY
static ps_s32 iMemInitialized = 0;
const ps_char *g_cur_file_name = "";
ps_u32 g_cur_line = 0;
/*
* Each of the blocks allocated begin with a header containing informations
*/
#define MEMTAG 0x5aa5
#define MEMTAILTAG 0x5a
#define MALLOC_TYPE 1
#define REALLOC_TYPE 2
#define STRDUP_TYPE 3
typedef struct memnod
{
ps_u32 mh_size;
ps_u32 mh_number;
struct memnod* mh_next;
struct memnod* mh_prev;
const ps_char * mh_file;
ps_u32 mh_line;
ps_u16 mh_type;
ps_u16 mh_tag;
} PS_MEMHDR;
typedef struct stmemtail
{
ps_u8 mt_tag1;
}PS_MEMTAIL;
#define HDR_SIZE sizeof(PS_MEMHDR)
#define TAIL_SIZE sizeof(PS_MEMTAIL)
static ps_u32 debugMemTimes=0;
static ps_u32 block=0;
static PS_MEMHDR* memlist = NULL;
static void debugmem_tag_error(void *addr);
static void debugmem_list_add(PS_MEMHDR *);
static void debugmem_list_delete(PS_MEMHDR *);
#define Mem_Tag_Err(a) debugmem_tag_error(a);
#define ALIGN_SIZE sizeof(double)
#define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1))/ ALIGN_SIZE ) * ALIGN_SIZE)
#define CLIENT_2_HDR(a) ((PS_MEMHDR *) (((ps_s8 *) (a)) - RESERVE_SIZE ))
#define HDR_2_CLIENT(a) ((void *) (((ps_s8 *) (a)) + RESERVE_SIZE ))
#define max_alloc_size (4608 * 1024L)
static void debugmem_tag_error(void *addr)
{
PS_MEMHDR * p = (PS_MEMHDR *)addr;
printf( ASSERT_STRING );
printf( "Free in file : %s line: %d\n", g_cur_file_name, g_cur_line );
printf( "malloc in file : %s line: %d\n", p->mh_file, p->mh_line );
PS_ASSERT( 0 );
}
static ps_int
ps_InitMemory( void )
{
if ( iMemInitialized )
return -1;
iMemInitialized = 1;
return 0;
}
/**
* ps_memMalloc:
* @size: an ps_u32 specifying the size in byte to allocate.
* @file: the file name or NULL
* @line: the line number
*
* a psMalloc() equivalent, with logging of the allocation info.
*
* Returns a pointer to the allocated area or NULL in case of lack of memory.
*/
void *
ps_memMalloc( ps_u32 size )
{
PS_MEMHDR *p;
if ( !iMemInitialized )
ps_InitMemory();
p = (PS_MEMHDR *)malloc( RESERVE_SIZE +TAIL_SIZE + size );
if ( !p )
{
return ( NULL );
}
p->mh_size = size;
p->mh_number = ++block;
p->mh_file = g_cur_file_name;
p->mh_line = g_cur_line;
p->mh_type = MALLOC_TYPE;
p->mh_tag = MEMTAG;
debugMemTimes++;
debugmem_list_add(p);
{
PS_MEMTAIL *tail;
tail = (PS_MEMTAIL*)((ps_s8 *)p +RESERVE_SIZE+ size) ;
tail->mt_tag1 = MEMTAILTAG;
}
return ( HDR_2_CLIENT(p) );
}
void *
ps_memCalloc( ps_u32 size, ps_u32 num )
{
void * p;
p = ps_memMalloc( size * num );
if ( p )
{
memset( p, 0, size * num );
return p;
}
return NULL;
}
/**
* ps_memRealloc:
* @ptr: the initial memory block pointer
* @size: an itkINT32 specifying the size in byte to allocate.
* @file: the file name or NULL
* @line: the line number
*
* a realloc() equivalent, with logging of the allocation info.
*
* Returns a pointer to the allocated area or NULL in case of lack of memory.
*/
void *
ps_memRealloc( void *ptr, ps_u32 size )
{
PS_MEMHDR *p;
ps_u32 number;
if ( !iMemInitialized )
ps_InitMemory();
if( !ptr ){
if(size)
return ps_memMalloc(size);
else
return NULL;
}
p = CLIENT_2_HDR( ptr );
number = p->mh_number;
if (p->mh_tag != MEMTAG)
{
Mem_Tag_Err(p);
goto error;
}
p->mh_tag = ~MEMTAG;
debugMemTimes--;
debugmem_list_delete(p);
p = (PS_MEMHDR *)realloc( p, RESERVE_SIZE +TAIL_SIZE + size );
if ( !p )
{
goto error;
}
p->mh_number = number;
p->mh_file = g_cur_file_name;
p->mh_line = g_cur_line;
p->mh_type = REALLOC_TYPE;
p->mh_tag = MEMTAG;
debugMemTimes++;
debugmem_list_add(p);
{
PS_MEMTAIL *tail;
tail = (PS_MEMTAIL*)((ps_s8 *)p +RESERVE_SIZE+ size ) ;
tail->mt_tag1 = MEMTAILTAG;
}
return ( HDR_2_CLIENT(p) );
error:
return ( NULL );
}
/**
* ps_memFree:
* @ptr: the memory block pointer
*
* a ps_free() equivalent, with error checking.
*/
void
ps_memFree( void *ptr )
{
PS_MEMHDR *p;
if ( !ptr )
return;
p = CLIENT_2_HDR( ptr );
{
if ( p->mh_tag != MEMTAG )
{
Mem_Tag_Err(p);
goto error;
}
p->mh_tag = ~MEMTAG;
{
PS_MEMTAIL *tail;
tail = (PS_MEMTAIL*)((ps_s8 *)p +RESERVE_SIZE+ p->mh_size ) ;
if ( tail->mt_tag1 != MEMTAILTAG )
{
Mem_Tag_Err(p);
goto error;
}
tail->mt_tag1 = ~MEMTAILTAG;
}
debugMemTimes--;
debugmem_list_delete(p);
}
free(p);
return;
error:
return;
}
static void debugmem_list_add(PS_MEMHDR *p)
{
p->mh_next = memlist;
p->mh_prev = NULL;
if (memlist) memlist->mh_prev = p;
memlist = p;
}
static void debugmem_list_delete(PS_MEMHDR *p)
{
if (p->mh_next)
p->mh_next->mh_prev = p->mh_prev;
if (p->mh_prev)
p->mh_prev->mh_next = p->mh_next;
else memlist = p->mh_next;
}
void ps_OutputDebugString( ps_bool bAssert, const ps_char *lpOutputString)
{
//do some thing
if( !bAssert )
printf( lpOutputString );
}
void ps_memlist_DBGMemoryLeak( void )
{
if ( memlist )
{
PS_MEMHDR* head=memlist;
ps_s32 i=0;
ps_OutputDebugString( PS_TRUE, "Browser Memory Leak Dump Start...\r\n" );
while( head )
{
ps_s8 szBuf[1024]={0};
sprintf(szBuf,"<%04d===>0x%x > Memory Leak at file:%s line:%4d Size: %d \r\n",
i++, (ps_u32)HDR_2_CLIENT(head), head->mh_file, head->mh_line, head->mh_size );
ps_OutputDebugString( PS_FALSE, szBuf );
head = head->mh_next;
}
ps_OutputDebugString( PS_TRUE, "Browser Memory Leak Dump end...\r\n" );
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -