📄 pbl.c
字号:
/* pbl.c - basic library functions Copyright (C) 2002 Peter Graf This file is part of PBL - The Program Base Library. PBL is free software. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For more information on the Program Base Library or Peter Graf, please see: http://mission.base.com/. $Log: pbl.c,v $ Revision 1.2 2002/09/12 20:47:13 peter added the isam file handling to the library*//* * make sure "strings <exe> | grep Id | sort -u" shows the source file versions */static char* _PBL_id = "$Id: pbl.c,v 1.2 2002/09/12 20:47:13 peter Exp $";static int _PBL_fct() { return( _PBL_id ? 0 : _PBL_fct() ); }#include <stdio.h>#include <string.h>#include <memory.h>#include <malloc.h>#include <time.h>#include "pbl.h"/*****************************************************************************//* #defines *//*****************************************************************************//*****************************************************************************//* typedefs *//*****************************************************************************//* * the type is only needed if we keep a heap memory trace */typedef struct pbl_memtrace_s{ char * tag; /* tag used by calling function */ time_t time; /* time when the chunk of memory was requested */ void * data; /* pointer to data that was allocated */ size_t size; /* number of bytes allocated */ struct pbl_memtrace_s * next; /* memory chunks are kept in a linear */ struct pbl_memtrace_s * prev; /* list */} pbl_memtrace_t;/*****************************************************************************//* globals *//*****************************************************************************/#ifdef PBL_MEMTRACE/* * head and tail of known memory chunks */static pbl_memtrace_t * pbl_memtrace_head;static pbl_memtrace_t * pbl_memtrace_tail;/* * number of memory chunks known */static long pbl_nmem_chunks = 0;/* * total size of all chunks known */static long pbl_nmem_size = 0;#endifstatic char pbl_errbuf[ PBL_ERRSTR_LEN + 1 ];int pbl_errno;char * pbl_errstr = pbl_errbuf;/*****************************************************************************//* functions *//*****************************************************************************/#ifdef PBL_MEMTRACE/* * log a line for all memory chunks that are allocated for more than * 3 minutes, or if call at the end of the program, log all chunks known */void pbl_memtrace_out( int checktime ){ static int first = 1; pbl_memtrace_t * memtrace; pbl_memtrace_t * tmp; char * outpath = "pblmemtrace.log"; FILE * outfile = NULL; time_t now = time( 0 ); char * nowstr = NULL; char * timestr = NULL; if( !pbl_memtrace_head ) { return; } memtrace = pbl_memtrace_head; while( memtrace ) { if( checktime && ( now - memtrace->time < 180 )) { break; } if( !outfile ) { if( first ) { first = 0; outfile = fopen( outpath, "w" ); if( outfile ) { fprintf( outfile, ">>memtrace at %s", ctime( &now )); } } else { outfile = fopen( outpath, "a" ); } if( !outfile ) { break; } } tmp = memtrace; memtrace = memtrace->next; if( !nowstr ) { nowstr = strdup( ctime( &now )); } timestr = ctime( &(tmp->time)); fprintf( outfile, "%s %.*s: %.*s %06ld %x %ld %ld \"%s\"\n", checktime ? ">" : "e", 8, nowstr ? nowstr + 11 : "unknown", 8, timestr ? timestr + 11 : "unknown", (long)tmp->size, tmp->data - NULL, pbl_nmem_chunks, pbl_nmem_size, tmp->tag ); PBL_LIST_UNLINK( pbl_memtrace_head, pbl_memtrace_tail, tmp, next, prev ); free( tmp ); } if( nowstr ) { free( nowstr ); } if( outfile ) { fclose( outfile ); }}/* * remember a memory chunk that was allocated by some function */void pbl_memtrace_create( char * tag,void * data,size_t size){ pbl_memtrace_t * memtrace; memtrace = malloc( sizeof( pbl_memtrace_t )); if( !memtrace ) { return; } memtrace->tag = tag; memtrace->time = time( 0 ); memtrace->data = data; memtrace->size = size; PBL_LIST_APPEND( pbl_memtrace_head, pbl_memtrace_tail, memtrace, next, prev ); pbl_nmem_chunks++; pbl_nmem_size += size; pbl_memtrace_out( 1 );}/* * remove a memory from the chunk list, the caller freed the memory */void pbl_memtrace_delete(void * data){ pbl_memtrace_t * memtrace; for( memtrace = pbl_memtrace_head; memtrace; memtrace = memtrace->next ) { if( memtrace->data == data ) { pbl_nmem_chunks--; pbl_nmem_size -= memtrace->size; PBL_LIST_UNLINK( pbl_memtrace_head, pbl_memtrace_tail, memtrace, next, prev ); free( memtrace ); break; } }}#endif /* PBL_MEMTRACE *//** * replacement for malloc * * @return void * retptr == NULL: OUT OF MEMORY * @return void * retptr != NULL: pointer to buffer allocated */void * pbl_malloc(char * tag, /** tag used for memory leak detection */size_t size /** number of bytes to allocate */){ void * ptr; if( !tag ) { tag = "pbl_malloc"; } ptr = malloc( size ); if( !ptr ) { snprintf( pbl_errstr, PBL_ERRSTR_LEN, "%s: failed to malloc %d bytes\n", tag, size ); pbl_errno = PBL_ERROR_OUT_OF_MEMORY; return( 0 ); }#ifdef PBL_MEMTRACE pbl_memtrace_create( tag, ptr, size );#endif return( ptr );}/** * replacement for malloc, initializes the memory to 0 * * @return void * retptr == NULL: OUT OF MEMORY * @return void * retptr != NULL: pointer to buffer allocated */void * pbl_malloc0(char * tag, /** tag used for memory leak detection */size_t size /** number of bytes to allocate */){ void * ptr = malloc( size ); if( !ptr ) { snprintf( pbl_errstr, PBL_ERRSTR_LEN, "failed to malloc %d bytes\n", size ); pbl_errno = PBL_ERROR_OUT_OF_MEMORY; return( 0 ); } memset( ptr, 0, size );#ifdef PBL_MEMTRACE pbl_memtrace_create( tag, ptr, size );#endif return( ptr );}/** * duplicate a buffer, similar to strdup * * @return void * retptr == NULL: OUT OF MEMORY * @return void * retptr != NULL: pointer to buffer allocated */void * pbl_memdup(char * tag, /** tag used for memory leak detection */void * data, /** buffer to duplicate */size_t size /** size of that buffer */){ void * ptr = malloc( size ); if( !ptr ) { snprintf( pbl_errstr, PBL_ERRSTR_LEN, "failed to malloc %d bytes\n", size ); pbl_errno = PBL_ERROR_OUT_OF_MEMORY; return( 0 ); } memcpy( ptr, data, size );#ifdef PBL_MEMTRACE pbl_memtrace_create( tag, ptr, size );#endif return( ptr );}/** * duplicate and concatenate two memory buffers * * @return void * retptr == NULL: OUT OF MEMORY * @return void * retptr != NULL: pointer to new buffer allocated */void * pbl_mem2dup(char * tag, /** tag used for memory leak detection */void * mem1, /** first buffer to duplicate */size_t len1, /** length of first buffer */void * mem2, /** second buffer to duplicate */size_t len2 /** length of second buffer */){ void * ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -