⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmem.c

📁 Extended C/C++ Dynamic Memory Control And Debug Library
💻 C
📖 第 1 页 / 共 5 页
字号:
 #pragma message("XMEM 4 byte / 32 bit pointer -> XMEM_32BIT")
#elif (__linux__ && __x86_64__)                 /* Linux 64 bit */
 #define PTRFMT               "%016lx"          /* 8 byte / 64 bit pointer size */
 #define PTRCAST              ptrdiff_t         /* ??? */
 #define XMEM_64BIT           1
 #pragma message("XMEM 8 byte / 64 bit pointer -> XMEM_64BIT")
#elif __linux__                                 /* Linux 32 bit */
 #define PTRFMT               "%08lx"           /* 4 byte / 32 bit pointer size */
 #define PTRCAST              unsigned long     /* only this works ... */
 #define XMEM_32BIT           1
 #pragma message("XMEM 4 byte / 32 bit pointer -> XMEM_32BIT")
#elif __GNUC__                                  /* GNU C/C++ (DJGPP) */
 #define PTRFMT               "%08lx"           /* 4 byte / 32 bit pointer size */
 #define PTRCAST              ptrdiff_t
 #define XMEM_32BIT           1
 #pragma message("XMEM 4 byte / 32 bit pointer -> XMEM_32BIT")
#else                                           /* unknown compiler / target */
 #define PTRFMT               "%08lx"           /* 4 byte / 32 bit pointer size */
 #define PTRCAST              long
 #define XMEM_32BIT           1
 #pragma message(">>>> XMEM unknown pointer size, assuming 4 byte / 32 bit pointer -> XMEM_32BIT <<<<")
#endif

/*****************************************************************************/
/* */
/*****************************************************************************/
#if __GNUC__ || (_WIN32 && (_MSC_VER < 1100))
#if XMEM_TEST_MCB
 #pragma message(">>> XMEM_TEST_MCB disabled!!!")
#endif
#undef XMEM_TEST_MCB
#define XMEM_TEST_MCB   0       /* actually only MS-C and Borland C, otherwise not possible */
#endif

/*****************************************************************************/
/*****************************************************************************/
/* local XMEM functions */
/*****************************************************************************/
/*****************************************************************************/
void   *xmem_store_pointer(void *, size_t, SGN08 * _WHERE(const SGN08 *, const SGN08 *, UNS32));
#if XMEM_ASPECTCPP && !XMEM_WHERE
void   *xmem_store_pointer(void *, size_t, SGN08 *, const SGN08 *, const SGN08 *, UNS32);
#endif
void    xmem_delete_pointer(void *, SGN08 *       _WHERE(const SGN08 *, const SGN08 *, UNS32));
#if XMEM_ASPECTCPP && !XMEM_WHERE
void    xmem_delete_pointer(void *, SGN08 *, const SGN08 *, const SGN08 *, UNS32);
#endif
void   *xmem_find_ptr(void *);
static  size_t  xmem_get_size(void *);
static  UNS32   xmem_get_allocation_id(void *);
static  void    xmem_test_ptr(void *, SGN08 *             _WHERE(const SGN08 *, const SGN08 *, UNS32));
static  void    xmem_test_guard(void *, size_t, UNS32, UNS32, SGN08 * _WHERE(const SGN08 *, const SGN08 *, UNS32)
                                                          _WHERE(const SGN08 *, const SGN08 *, UNS32));
#if (!XMEM_QUIET || XMEM_FORCE_OUTPUT) && (XMEM_STR || XMEM_MEM || XMEM_FILE)
#if 0
static  void    xmem_test_overflow(void *, size_t, SGN08 * _WHERE(const SGN08 *, const SGN08 *, UNS32));
#endif
static  void    xmem_test_boundary(void *, size_t, SGN08 * _WHERE(const SGN08 *, const SGN08 *, UNS32));
#endif
#if (!XMEM_QUIET || XMEM_FORCE_OUTPUT) && XMEM_STR && XMEM_STREOS
static  void    xmem_test_string(SGN08 *, SGN08 *         _WHERE(const SGN08 *, const SGN08 *, UNS32));
#endif
static  void   *xmem_alloc_pointer(size_t, SGN08 *        _WHERE(const SGN08 *, const SGN08 *, UNS32));
static  void    xmem_free_pointer(void *, SGN08 *         _WHERE(const SGN08 *, const SGN08 *, UNS32));
static  void    xmem_find_change(void *, void *, size_t);
#if !XMEM_QUIET || XMEM_FORCE_OUTPUT
static  BOOLEAN xmem_test_used(UNS08 *, size_t);
#endif
static  BOOLEAN xmem_test_size(size_t                     _WHERE(const SGN08 *, const SGN08 *, UNS32));
#if XMEM_TEST_MCB
static  BOOLEAN xmem_test_mcb(void *, size_t              _WHERE(const SGN08 *, const SGN08 *, UNS32));
#endif
#if XMEM_TEST_NULL
static  void    xmem_test_null(void *, size_t             _WHERE(const SGN08 *, const SGN08 *, UNS32));
#endif
static  void    xmem_internal_null(void);
#if XMEM_STRESS
static  BOOLEAN xmem_stressed(void);
#endif
static void     xmem_check_scope(const SGN08 *callname, const SGN08 *fname, UNS32 line);
#if XMEM_STREOS
 #define XMEM_TEST_STRING(a)    xmem_test_string a
#else
 #define XMEM_TEST_STRING(a)
#endif

/*****************************************************************************/
/*****************************************************************************/
/* output redirection */
/*****************************************************************************/
/*****************************************************************************/
static int  xmem_printf(const char *, ...);     /* the XMEM printf() */

#if !XMEM_QUIET || XMEM_FORCE_OUTPUT || XMEM_OUTPUTDEBUGSTRING
#define XMEM_MSG_BUFLEN         4000
static char xmem_msg_buffer[XMEM_MSG_BUFLEN];   /* large text buffer */
#endif

#if UNICODE
 #define PTR2STR    LPCWSTR
#else
 #define PTR2STR    LPCSTR
#endif

#if !_WINDOWS           /**** not WINDOWS ****/

 #if _WIN32
  #if XMEM_OUTPUTDEBUGSTRING
    static void (__stdcall *xmem_output_function)(PTR2STR) = OutputDebugString;
  #else
    static void (__stdcall *xmem_output_function)(PTR2STR) = NULL;
  #endif
 #endif

 #if !XMEM_QUIET || XMEM_FORCE_OUTPUT
  static int  (*xmem_output_function_int_vararg)(const char *, ...) = printf;
  static void (*xmem_output_function_void_vararg)(const char *, ...) = NULL;
 #endif

#else                   /**** WINDOWS ****/

 #if XMEM_OUTPUTDEBUGSTRING
  static void (__stdcall *xmem_output_function)(const char *) = OutputDebugString;
 #else
  static void (__stdcall *xmem_output_function)(const char *) = NULL;
 #endif

 #if !XMEM_QUIET || XMEM_FORCE_OUTPUT
  static int  (*xmem_output_function_int_vararg)(const char *, ...) = NULL;
  static void (*xmem_output_function_void_vararg)(const char *, ...) = NULL;
 #endif

#endif                  /**** WINDOWS ****/

#if XMEM_CALLTRACE                      /* XMEM function call trace */
 #define TRACEPRT(a)    xmem_printf a
 #define TRACELOC(a)    MEM_LOCATE a
 #if !XMEM_QUIET || XMEM_FORCE_OUTPUT
  #define TRACEFFLUSH() fflush(stdout)
 #else
  #define TRACEFFLUSH()
 #endif
#else                                   /* no XMEM function call trace */
 #define TRACEPRT(a)
 #define TRACELOC(a)
 #define TRACEFFLUSH()
#endif          /* XMEM_CALLTRACE */

#if !XMEM_QUIET || XMEM_FORCE_OUTPUT
 #define FFLUSH()       fflush(stdout)
#else
 #define FFLUSH()
#endif

/*****************************************************************************/
/*****************************************************************************/
/* XMEM logfile */
/*****************************************************************************/
/*****************************************************************************/
#if XMEM_LOGFILE
static void xmem_logfile(SGN08 *, PTRCAST, size_t, UNS32 _WHERE(const SGN08 *, const SGN08 *, UNS32));
 #define LOGFILE(a)      xmem_logfile a
#else
 #define LOGFILE(a)
#endif

#define LOGFILE_ERROR_TRACE   0

/*****************************************************************************/
/*****************************************************************************/
/* XMEM dialog */
/*****************************************************************************/
/*****************************************************************************/
#if XMEM_DIALOG
 #define XMEM_COLLECT_DIALOG()          xmem_collect_dialog()
 #define XMEM_SHOW_DIALOG()             xmem_show_dialog()

 static void xmem_collect_dialog(void);
 static void xmem_show_dialog(void);

 #define XMEM_DIALOG_BUFLENGTH          20000
 static SGN08 dialog_buffer[XMEM_DIALOG_BUFLENGTH + 1];
 static BOOLEAN flag_collect_dialog = FALSE;
 static BOOLEAN flag_show_dialog = TRUE;
#else
 #define XMEM_COLLECT_DIALOG()
 #define XMEM_SHOW_DIALOG()
#endif

/*****************************************************************************/
/*****************************************************************************/
/* XMEM Browser */
/*****************************************************************************/
/*****************************************************************************/
#if XMEM_BROWSER
#define XMEM_MSG_COUNTERS               1
#define XMEM_MSG_STATS                  2
#define XMEM_MSG_TEXT                   3
#define XMEM_MSG_LOG                    4
void xmem_send_msg(UNS32);
#define xmem_send_counters()            xmem_send_msg(XMEM_MSG_COUNTERS)
#define xmem_send_stats()               xmem_send_msg(XMEM_MSG_STATS)
#define xmem_send_text()                xmem_send_msg(XMEM_MSG_TEXT)
#define xmem_send_log()                 xmem_send_msg(XMEM_MSG_LOG)
#else
#define xmem_send_counters()
#define xmem_send_stats()
#define xmem_send_text()
#define xmem_send_log()
#endif

/*****************************************************************************/
/*****************************************************************************/
/* local defines */
/*****************************************************************************/
/*****************************************************************************/
#ifndef XMEM_TRACE
/**** XMEM_TRACE is used for the selection of the XMEM memory trace type ****/
#define XMEM_TRACE      1       /* 0 == off */
                                /* 1 == memory trace */
                                /* 2 == memory trace with alloc copy, will catch later overwrites */

/* NOTE: XMEM_TRACE == 2 and XMEM_FREENULL != 0 makes no sense because the */
/* freed pointer will point to NULL and not to the freed memory block ! */
#endif          /* XMEM_TRACE */

#if XMEM_PEDANTIC       /* perform numerous checks in all functions (quite pedantic) */
 #define CHECKPOINT()   xmem_overwrite(FUNCTION_UNKNOWN,"internal",0)
#else
 #define CHECKPOINT()
#endif          /* XMEM_PEDANTIC */

/**** trace for user selected breaks ****/
#define TRACE_NUMBERS               1

/**** free leaking blocks by increasing number ****/
#ifndef XMEM_FREE_INCREASE_ORDER
#define XMEM_FREE_INCREASE_ORDER    1
#endif

/**** test for failed allocation ****/
#if !XMEM_TEST_NULL     /* if no NULL test, remove function calls */
 #if XMEM_WHERE
  #define xmem_test_null(a, b, c, d, e)
 #else
  #define xmem_test_null(a, b)
 #endif
#endif          /* !XMEM_TEST_NULL */

/**** HASH values ****/
#if !__GNUC__ && !_WIN32
 #define XMEM_HASHSIZE   29     /* must be odd number, best choice is prime */
                                /* (13, 23, 29, 31, 61, 127, 251, ...) */
                                /* smaller values: lower memory consumption */
                                /* larger values: faster execution */
 #define SLOTSIZE        8
#else
 #define XMEM_HASHSIZE   61     /* use larger values for 32 bit compilers */
 #define SLOTSIZE        16
#endif

#if (XMEM_HASHSIZE % 2) == 0    /* check hash size value for correctness */
 #error XMEM_HASHSIZE must be odd number!
#endif

#if 1                   /* hash value calculation with macro */
 #define HASHVALUE(p)   ((PTRCAST)(p) % XMEM_HASHSIZE)   /* quite simple calculation with modulo operation */
#else                   /* hash value calculation with function */
UNS32 hashvalue(void *p)
{
  UNS32 value;
  value = (((UNS32)(p)) % XMEM_HASHSIZE);   /* quite simple calculation with modulo operation */
  return(value);
}
#define HASHVALUE(p)    hashvalue(p)
#endif

/**** overhead regions (guarding "fence") before and after memory block ****/
#if XMEM_GUARD
 #ifndef OVHDBEG
  #define OVHDBEG       8       /* should be multiple of natural alignment (4, 8, ?) */
 #endif
 #ifndef OVHDEND
  #define OVHDEND       8       /* should be multiple of natural alignment (4, 8, ?) */
 #endif
 #pragma message("XMEM_GUARD enabled")
#else   /* no guard region */
 #define OVHDBEG        0       /* no guarding regions */
 #define OVHDEND        0       /* no guarding regions */
#endif          /* XMEM_GUARD */

#if ((OVHDBEG) < 0) || ((OVHDEND) < 0)
 #error overhead value < 0
#endif
#if ((OVHDBEG) % 4) || ((OVHDEND) % 4)
 #error overhead size alignment incorrect, should be 4 or multiple of 4
#endif

#define OVHDSIZE        ((OVHDBEG) + (OVHDEND))         /* total overhead added */

#if (OVHDBEG > 0)
  #define CLEAR_OVHDBEG(a,b,c)    memset(a,b,c)
#else
  #define CLEAR_OVHDBEG(a,b,c)
#endif
#if (OVHDEND > 0)
  #define CLEAR_OVHDEND(a,b,c)    memset(a,b,c)
#else
  #define CLEAR_OVHDEND(a,b,c)
#endif

/**** pattern characters for allocated regions ****/
/**** NOTE: 0x00 or 0xff are not a good choice! ****/
#define BEGFILLCHAR     0x9D    /* before allocated area */
#define ENDFILLCHAR     0xD9    /* after allocated area */
#define ALLOCFILLCHAR   0xFB    /* allocated area */
#define FREEFILLCHAR    0xFD    /* freed area */

#if !__GNUC__ && !_WIN32
 #define TEST_SIZE      1       /* test requested allocation size for 64k limit */
                                /* only useful for 16 bit systems */
#else
 #define TEST_SIZE      1       /* test requested allocation size for 2^32-1 limit */
                                /* only useful for 32 bit systems, assumes that */
                                /* 'size_t' = 'unsigned int' = 32 bit */
#endif

/**** memory control blocks (MCB) ****/
#if XMEM_TEST_MCB
 #define xmem_test_mcb_(a)               xmem_test_mcb a
 #if defined(_MSC_VER)
  #if !_WIN32
   #define MCB_MEMSIZE(p)  *((unsigned int *)((char *)(p) - 2))     /* Microsoft */
  #elif _MSC_VER >= 1100
   #define MCB_MEMSIZE(p)  _msize(p)                                /* Microsoft */
  #elif _MSC_VER < 1100
   #error MCB functionality requires MS VC++ 5.0 or higher
  #endif
 #elif __TURBOC__
  #define MCB_MEMSIZE(p)  *((unsigned int *)((char *)(p) - 4))      /* Turbo C++ */
 #else
  #error MCB_MEMSIZE: unknown compiler
 #endif
#else           /* XMEM_TEST_MCB */
 #define xmem_test_mcb_(a)               0                          /* undefine it */
#endif          /* XMEM_TEST_MCB */

/**** address calculation macros ****/
#if !__GNUC__ && !_WIN32
 #if M_I86LM || __LARGE__       /**** large model: 4 byte pointer ****/
 /* calculate linear adress from segment:offset pointer value (MS-DOS) */
 /* 2 byte segment, 2 byte offset */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -