📄 xmemtest.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 + -