📄 memchk.c
字号:
/* * -*- 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 *//* #ifdef __GNUC__ */#include <string.h>/* #endif */#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, short 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, short 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, short 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. */void PrintLeaks ( void ){ struct BlockHeader* q = _AllocListHead; long count = 0; while (q) { if (q->time >= _BeginTime) count++; q = q->next; } if (count) { fprintf (stderr, "\nMemory leaks:\n" "------------\n"); 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; } } _AllocListHead = _AllocListTail = 0;}/* * FreeLeaks functions: frees intermediate allocated memory that cannot * be free'd by any other mean since an unexpected * error has occurred. */void FreeLeaks ( void ){ 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 (tmp); } q = tmp; } } _AllocListHead = _AllocListTail = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -