?? memchk.c
字號(hào):
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Adapted/reformated to suit my own coding style. Some changes to the
* printing. Also the defintion that enable/disable the memory checker.
* Added a few functions and definitions.
*
* Mow-Song, Ng 2/9/2002
* msng@mmu.edu.my
* http://www.pesona.mmu.edu.my/~msng
*
* I do not claim copyright to the code, but if you use them or modify them,
* please drop me a mail.
*
*/
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Original code from LiftPack */
/*
* -*- Mode: ANSI C -*-
* $Id: memchk.c,v 1.7 1996/11/18 18:49:11 fernande Exp $
* $Header: /sgi.acct/sweldens/cvs/liftpack/Util/memchk.c,v 1.7
* 1996/11/18 18:49:11 fernande Exp $
* Author: M. A. Sridhar
* Modified: Gabriel Fernandez
*
* This file has a memory leak checker which keeps track of all the
* allocations and deallocations in order to see if some previously
* allocated memory is not freed at the end of the execution of the
* code.
* The functions included are malloc, calloc, realloc, and free.
*
* NOTE: It is important tht this program is not combined with any
* other memory handler, because a list of allocations and
* deallocations is kept with every call to 'malloc', 'calloc',
* 'realloc', and 'free'. If 'free' is used to deallocate a
* memory segment allocated with other function that the ones in
* this file, the program will segment fault because is trying to
* delete a list entry which does not exists.
*/
/* do not edit anything above this line */
#include <string.h>
#include "memchk.h"
#undef calloc
#undef realloc
#undef malloc
#undef free
#include <malloc.h>
#include <stdio.h>
typedef unsigned long uLong;
typedef unsigned char uChar;
uLong magic_cookie = 0xf9a42bb1; /* Used to indicate "allocated" state */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
struct BlockHeader {
uLong marker;
long time;
struct BlockHeader* prev;
struct BlockHeader* next;
char* file;
long lineNo;
long size;
#ifdef DOUBLE
uChar dummy[4]; /* pad structure to a power of two */
#endif
};
/* --------------------- Static variables --------------------------------- */
static struct BlockHeader* _AllocListHead = 0; /* Head of list of */
/* allocated blocks */
static struct BlockHeader* _AllocListTail = 0; /* Tail of list of */
/* allocated blocks */
static short _LeakCheckerActive = 0;
static long _Time = 0; /* Clock: ticks on every new and */
/* delete */
static long _MaxMem = 0; /* Max memory used so far */
static long _CurrentAlloc = 0; /* Amount of memory currently */
/* allocated */
static long _BeginTime = 0; /* Time at which leack checker was */
/* instantiated */
/*------------------------------------------------------------------------- */
/* code */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*
* Calloc function: same as Malloc, but initializes the content with
* zeros.
*/
void *Calloc ( size_t n, size_t s, int line_no, char *file_name )
{
size_t size = n*s;
uChar *buffer = (uChar *)Malloc ( size, line_no, file_name );
int i;
for ( i=0 ; i<(int)size ; i++ )
buffer[i] = 0;
return buffer;
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*
* Realloc function: reallocates a contiguous segment of memory using
* the same pointer variable.
*/
void *Realloc ( void *p, size_t s, int line_no, char *file_name )
{
uChar *newp;
struct BlockHeader* q;
/* Check for integrity of memory in p */
q = (struct BlockHeader*)
( (uChar*) p - sizeof (struct BlockHeader));
if (q->marker != magic_cookie && _LeakCheckerActive)
fprintf (stderr, "Realloc(%8lx): memory corrupted", (long)p);
/* Allocate new segment and copy p into it */
newp = (uChar *)Malloc ( s, line_no, file_name );
newp = (uChar *)memcpy (newp, p, (size_t)q->size);
/* Free p and return new segment */
Free (p);
return (void *)newp;
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*
* Malloc function: uses a linked list to keep track of all the memory
* segments that have been allocated so far. It
* includes information about the size of the segment,
* the file where the allocation was done, the line
* where the function was called, and the order in
* which the call was executed.
*/
void* Malloc (size_t n, int line_no, char* file_name)
{
struct BlockHeader* q;
long size;
uChar* p;
if (n == 0)
return NULL;
size = (long)n;
/* Allocate extra bytes */
p = (uChar*) malloc (n + sizeof (struct BlockHeader));
if (!p) {
fprintf (stderr, "Malloc(): allocating %u bytes: no memory!", n);
exit (1);
}
_CurrentAlloc += (long)n;
if (_CurrentAlloc > _MaxMem)
_MaxMem = _CurrentAlloc;
q = (struct BlockHeader*) p;
/* Put a magic marker */
q->marker = magic_cookie;
q->time = _Time++;
q->size = size;
q->file = file_name;
q->lineNo = (long)line_no;
memset (p + sizeof(struct BlockHeader), '\02', (unsigned int) size);
/* Uninitialized allocated memory has 02 in it */
/* Insert at tail of allocated list */
if (_AllocListTail) {
_AllocListTail->next = q;
q->prev = _AllocListTail;
q->next = 0;
_AllocListTail = q;
}
else {
_AllocListHead = _AllocListTail = q;
q->prev = q->next = 0;
}
return p + sizeof(struct BlockHeader);
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*
* Free function: frees previously allocated memory and puts 03 in
* it to verify later on. The entry in the linked list
* is removed and all the other entries are reorganized.
*/
void Free (void* p)
{
struct BlockHeader* q;
if ( p == NULL )
fprintf (stderr, "Free(%8lx): empty memory\n", (long)p);
q = (struct BlockHeader*)
( (uChar*) p - sizeof (struct BlockHeader));
if (q->marker != magic_cookie && _LeakCheckerActive)
fprintf (stderr, "Free(%8lx): memory corrupted\n", (long)p);
_CurrentAlloc -= q->size;
if (_AllocListHead) {
if (q->prev)
q->prev->next = q->next;
if (q->next)
q->next->prev = q->prev;
if (q == _AllocListHead)
_AllocListHead = q->next;
if (q == _AllocListTail)
_AllocListTail = q->prev;
memset (q, '\03', (unsigned int) (sizeof(struct BlockHeader) +
(unsigned int)q->size));
/* Freed memory has 03 in it */
}
free (q);
_Time++;
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*
* PrintLeaks function: this routine prints the content of the linked
* list with all the information about memory
* allocated so far. If everything that was
* allocated was freed, then the list should be
* empty and nothing should be printed.
*/
int PrintLeaks ()
{
#ifdef __MEMCHK_ENABLE_
struct BlockHeader* q = _AllocListHead;
long count = 0;
while (q) {
if (q->time >= _BeginTime)
count++;
q = q->next;
}
if (count) {
fprintf (stderr, "\nMemory status:\n"
"--------------\n");
fprintf(stderr, "Max:%d Current:%d\n", MaxMemory(), CurrentMemoryAllocated());
q = _AllocListHead;
while (q) {
if (q->time >= _BeginTime) {
/* Only output if the allocation occurred after the leak */
/* checker was created */
fprintf (stderr,
"Time: %ld Address: %08x Size: %ld line %d file '%s'\n",
q->time, (unsigned long)q, q->size,
(int)q->lineNo, q->file);
}
q = q->next;
}
return 1;
}
else{
//fprintf(stderr, "No allocated memory.\n");
return 0;
}
#else
return 0;
#endif
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*
* FreeLeaks functions: frees intermediate allocated memory that cannot
* be free'd by any other mean since an unexpected
* error has occurred.
*/
void FreeLeaks ()
{
#ifdef __MEMCHK_ENABLE_
struct BlockHeader* q = _AllocListHead;
struct BlockHeader* tmp;
long count = 0;
while (q) {
if (q->time >= _BeginTime)
count++;
q = q->next;
}
if (count) {
q = _AllocListHead;
while (q) {
tmp = q->next;
if (q->time >= _BeginTime) {
/* Only free if the allocation occurred after the leak */
/* checker was created */
free (q);
}
q = tmp;
}
}
_AllocListHead = _AllocListTail = 0;
_CurrentAlloc = 0;
#endif
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*
* MaxMemory functions: returns the maximum memory used so far.
*
*/
long MaxMemory()
{
#ifdef __MEMCHK_ENABLE_
return _MaxMem;
#else
return 0;
#endif
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*
* MaxMemory functions: returns the maximum memory used so far.
*
*/
long CurrentMemoryAllocated()
{
#ifdef __MEMCHK_ENABLE_
return _CurrentAlloc;
#else
return 0;
#endif
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -