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

📄 xmemtest.c

📁 Extended C/C++ Dynamic Memory Control And Debug Library
💻 C
字号:
/*****************************************************************************/
/*
    XMEMTEST.C - Tests for extended C/C++ Dynamic Memory Control And Debug Library

    Copyright (C) Juergen Mueller (J.M.) 1987-2008
    All rights reserved.

    You are expressly prohibited from selling this software in any form
    or removing this notice.

    THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
    EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THE
    IMPLIED WARRANTIES OF MERCHANTIBILITY, FITNESS FOR A PARTICULAR
    PURPOSE, OR NON-INFRINGEMENT. THE AUTHOR SHALL NOT BE LIABLE FOR
    ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
    OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. THE ENTIRE RISK
    AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM AND DOCUMENTATION
    IS WITH YOU.

    Permission to modify the code and to distribute modified code is granted,
    provided the above notices are retained, and a notice that the code was
    modified is included with the above copyright notice.

    written by: Juergen Mueller, D-70806 Kornwestheim, GERMANY

    FILE       : XMEMTEST.C
    REVISION   : 08-Apr-2008
                 22:43:57
 */
/*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

#include "xmem.h"

#if _MSC_VER >= 1400
#if !XMEM
#define strdup      _strdup
#endif
#endif

/*****************************************************************************/
/* classes/types */
/*****************************************************************************/
#ifdef __cplusplus          /* some dummy classes to demonstrate C++ features */
class C_T1                  /* class C_T1 */
{
public:
  C_T1()
  {
    m_a = 1;
    m_pdbl = new double;
    m_pstr = new char [10];
  };
  virtual ~C_T1()
  {
    m_a = 0;
    if (m_pdbl)
    {
      *m_pdbl = 1.0;
      delete m_pdbl;
    }
    if (m_pstr)
    {
      *m_pstr = '\0';
      delete [] m_pstr;
    }
  };

private:
  int m_a;
  double *m_pdbl;
  char *m_pstr;
};

class C_T2 : public C_T1    /* class C_T2 */
{
public:
  C_T2()
  {
    m_p = new C_T1 [2];
  };
  virtual ~C_T2()
  {
    if (m_p)
      delete [] m_p;
  };

private:
  C_T1 *m_p;
};

class C_T101                /* class C_T101 */
{
public:
  C_T101()
  {
    m_a = 1;
    m_pdbl = new double;
    m_pstr = new char [10];
  };
  virtual ~C_T101()
  {
    m_a = 0;
    if (m_pdbl)
    {
      *m_pdbl = 1.0;
      delete m_pdbl;
      m_pdbl = NULL;
    }
    if (m_pstr)
    {
      *m_pstr = '\0';
      delete [] m_pstr;
      m_pstr = NULL;
    }
  };

private:
  int m_a;
  double *m_pdbl;
  char *m_pstr;
};

class C_T102                /* class C_T102 */
{
public:
  C_T102()
  {
    m_t101 = new C_T101 [2];
  };
  virtual ~C_T102()
  {
    if (m_t101)
    {
      delete [] m_t101;
      m_t101 = NULL;
    }
  };

private:
  C_T101 *m_t101;
};

class C_T103                /* class C_T103 */
{
public:
  C_T103()
  {
    m_t102 = new C_T102;
  };
  virtual ~C_T103()
  {
    if (m_t102)
    {
      delete m_t102;
      m_t102 = NULL;
    }
  };

private:
  C_T102 *m_t102;
};

class C_T104                /* class C_T104 */
{
public:
  C_T104()
  {
    m_t103 = new C_T103;
  };
  virtual ~C_T104()
  {
    if (m_t103)
    {
      delete m_t103;
      m_t103 = NULL;
    }
  };

private:
  C_T103 *m_t103;
};

class C_T105                /* class C_T105 */
{
public:
  C_T105()
  {
    m_t104 = new C_T104;
  };
  virtual ~C_T105()
  {
    if (m_t104)
    {
      delete m_t104;
      m_t104 = NULL;
    }
  };

private:
  C_T104 *m_t104;
};
#endif

/*****************************************************************************/
/* external prototypes */
/*****************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
void xmem_tst1_function1(void);
void xmem_tst2_function1(void);
void xmem_tst3_function1(void);
void xmem_tst4_function1(void);
#ifdef __cplusplus
}
#endif

/*****************************************************************************/
/* prototypes */
/*****************************************************************************/
void subroutine1();

/*****************************************************************************/
/* global variables */
/*****************************************************************************/
char string[2000];

#ifdef __cplusplus
C_T2 c_t2_global;       /* global static object */
#endif

/*****************************************************************************/
/* XMEM main test function */
/*****************************************************************************/
int main(int argc, char *argv[])
{
  void *p1;
  char *p2;
  void *p3;

  argc = argc;      /* just to avoid warnings */
  argv = argv;      /* just to avoid warnings */

/******** prolog: initialization ********/
#if XMEM
#if !defined(__cplusplus) && !defined(XMEM_TRACE)
  xmem_set_memtrace(2);    /* enable XMEM, 2: do not really free, check for changes after free */
#endif
  xmem_message("This message comes from XMEM!");
#endif
/********                        ********/

#if !CLEAN
  free(p1);                         /* error: free an unitialized pointer */
  p2 = (char *)&p1;
  free(p2);                         /* error: free a stack value */
#endif

  p1 = malloc(2);                   /* allocate */
  free(p1);                         /* and free, nothing special */

  p2 = (char *)malloc(20);          /* allocate */
#if !XMEM_ASPECTCPP && !CLEAN
  p2[-1] = 0x00;                    /* error: write to wrong array index, buffer overrun */
  p2[20] = 0x00;                    /* error: write to wrong array index, buffer overrun */
#endif
  free(p2);                         /* free */

  p1 = malloc(10);                  /* allocate, but never free: error, this pointer leaks */
#if CLEAN
  free(p1);
#endif

#if !CLEAN
  p1 = malloc(0);                   /* allocate 0 bytes, never free: error, this pointer leaks */
#endif

#if !XMEM_ASPECTCPP && !CLEAN
  p3 = realloc(p3, 100);            /* error: reallocate an uninitialized pointer */
#endif
#if !CLEAN
  p3 = realloc(NULL, 100);          /* reallocate a NULL pointer */
#endif

  p3 = malloc(10);                  /* allocate */
#if !XMEM_ASPECTCPP
  p3 = realloc(p3, 0);              /* try to reallocate 0 bytes */
#endif
  free(p3);                         /* and free, nothing special */

#if !CLEAN
  p2 = (char *)0x03;                /* error: assign invalid address */
  free(p2);                         /* error: free irregular pointer */
#endif

  p2 = (char *)malloc(4);           /* allocate 4 bytes */
#if !XMEM_ASPECTCPP && !CLEAN
  sprintf(p2, "%d", 1234);          /* error: write 5 bytes (4 digits + '\0') to 4 bytes array */
#endif
  free(p2);                         /* free */
#if !XMEM_ASPECTCPP && !CLEAN
  *p2 = 'x';                        /* write to already freed memory */
  free(p2);                         /* free already freed memory */
#endif

#if !CLEAN
  p1 = malloc(0x0001ffffL);         /* try to allocate more than 64k bytes */
                                    /* behaviour depends on implementation */
                                    /* never free: error, this pointer (if really allocated) leaks */
#endif
#if !XMEM_ASPECTCPP && !CLEAN
  p1 = malloc(0xffffffffL);         /* try to allocate maximum of (2^32 -1) bytes */
                                    /* behaviour depends on implementation */
                                    /* never free: error, this pointer (if really allocated) leaks */
  p1 = calloc(0xffffffffL, 0xffffffffL);/* try to allocate maximum of ((2^32 - 1) * (2^32 - 1)) bytes */
                                    /* behaviour depends on implementation */
                                    /* never free: error, this pointer (if really allocated) leaks */
#endif

  p2 = (char *)malloc(strlen("hello world"));   /* allocate, size excludes trailing '\0' */
#if !CLEAN
#if !XMEM_ASPECTCPP
  strcpy(p2, "hello world");        /* copy string, error: trailing '\0' causes buffer overrun */
#endif
  p2 = strdup("hello world");       /* duplicate string (internal allocate) */
#endif
  free(p2);                         /* and free, nothing special */

  p2 = (char *)malloc(10);          /* allocate */
  strcpy(p2, "12345");              /* copy string with 5 chars, nothing special */
#if !CLEAN
#if !XMEM_ASPECTCPP
  strcat(p2, "67890");              /* catenate string with 5 chars, error: trailing '\0' causes buffer overrun */
#endif
#endif
  free(p2);                         /* free */

#if XMEM_ALLOCA                     /**** some alloca specific tests ****/
  p1 = alloca(20);                  /* alloca on stack */
  free(p1);                         /* error: attempt to free a local stack pointer */

  p1 = alloca(20);                  /* alloca on stack, but never free: that's okay */

  p1 = alloca(20);                  /* alloca on stack */
#if !CLEAN
  p1 = realloc(p1, 40);             /* error: attempt to reallocate a local stack pointer */
#endif
  free(p1);                         /* error: attempt to free a local stack pointer */
#endif

#if defined (_MSC_VER)
  p1 = malloc(100);
  p1 = _expand(p1, 100);
  p1 = _expand(p1, 60);
  p1 = _expand(p1, 120);
#endif

#ifdef __cplusplus                  /**** some C++ specific tests ****/

  p2 = new char;                    /* allocate */
  delete p2;                        /* and free, nothing special */

  p2 = new char [10];               /* allocate */
  delete [] p2;                     /* and free, nothing special */

  p2 = new char;                    /* allocate, but never free: error, this pointer leaks */
#if CLEAN
  delete p2;                        /* and free, nothing special */
#endif

  {
    C_T2 c_t2_local;                /* automatic stack variable, constructor allocates memory */
                                    /* will be immediately deleted when scope is left */
  }

  C_T2 *c_t2 = new C_T2;            /* allocate */
  delete c_t2;                      /* and free, nothing special */

  c_t2 = new C_T2;                  /* allocate, but never free: error, this pointer leaks */
#if CLEAN
  delete c_t2;
#endif

#if !CLEAN
  p2 = NULL;                        /* error: assign invalid address */
  delete p2;                        /* error: free irregular pointer */
#endif

  char *ptr;
  ptr = (char *)malloc(10);         /* C malloc */
#if CLEAN
  free(ptr);
#else
  delete ptr;                       /* error: C++ delete */
#endif

  ptr = (char *)malloc(10);         /* C malloc */
#if CLEAN
  free(ptr);
#else
  delete [] ptr;                    /* error: C++ delete array */
#endif

  ptr = new char;                   /* C++ new */
#if CLEAN
  delete ptr;
#else
  free(ptr);                        /* error: C free */
#endif

  ptr = new char [10];              /* C++ new array */
#if CLEAN
  delete [] ptr;
#else
  free(ptr);                        /* error: C free */
#endif

  ptr = new char;                   /* C++ new */
#if CLEAN
  delete ptr;
#else
  delete [] ptr;                    /* error: C++ delete array */
#endif

  ptr = new char [10];              /* C++ new array */
#if CLEAN
  delete [] ptr;
#else
  delete ptr;                       /* error: C++ delete */
#endif

  C_T1 *c_t1_array = new C_T1[3];   /* allocate object array */
#if CLEAN
  delete [] c_t1_array;
#else
  delete c_t1_array;                /* error: delete only single object */
#endif

  c_t1_array = new C_T1[5];         /* allocate object array */
#if CLEAN
  delete [] c_t1_array;
#else
  free(c_t1_array);                 /* error: C free */
#endif

  c_t1_array = new C_T1[7];         /* allocate object array, but never free */
#if CLEAN
  delete [] c_t1_array;
#endif

#if !CLEAN
  delete new int;                   /* consecutive new and delete */
#endif

  C_T105 *p_t105 = new C_T105;      /* test nested C++ new */
  if (p_t105 != NULL)
  {
    delete p_t105;                  /* test nested C++ delete and C++ delete stack */
    p_t105 = NULL;
  }

  delete new C_T105;                /* consecutive new delete */
                                    /* test nested C++ delete, nested C++ delete and C++ delete stack */

#endif                              /**** endif some C++ specific tests ****/

  subroutine1();                    /* subroutine call to show scope functionality */

#if XMEM_CALLSTACK                      /* XMEM_CALLSTACK */
  for (int i = 0; i < 20; ++i)
  {
    p2 = strdup("callstack test");
    free(p2);
  }
#endif

#if XMEM_ALLOC_LIB || XMEM_ALLOC_CALL
  xmem_tst1_function1();            /* some tests concerning library call interception */
  xmem_tst2_function1();
  xmem_tst3_function1();
  xmem_tst4_function1();
#endif

/******** epilog: clean-up ********/
#if XMEM
#if !defined(__cplusplus)
  xmem_check_free();
#endif
#endif
/********                  ********/

  return(0);
}
/*****************************************************************************/
/* dummy function */
/*****************************************************************************/
void subroutine1()
{
  void *ptr;

#if XMEM
  xmem_enter_scope();           /* enter this scope level */
  xmem_enter_scope();           /* this one is incorrect */
#endif

  ptr = malloc(10);             /* this pointer leaks */
#if CLEAN
  free(ptr);
#endif

#if XMEM
  xmem_leave_scope();           /* enter this scope level */
#endif
}
/*****************************************************************************/

⌨️ 快捷键说明

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