📄 mymem.c
字号:
/*------------------------------------------------------------------------*/
/** Custom realloc function with memory event recording. */
void* CU_realloc(void *ptr, size_t size, unsigned int uiLine, const char* szFileName)
{
void* pVoid = NULL;
deallocate_memory(ptr, uiLine, szFileName);
#ifdef CUNIT_BUILD_TESTS
if (CU_FALSE == f_bTestCunitMallocActive) {
free(ptr);
return NULL;
}
#endif
pVoid = realloc(ptr, size);
if (NULL != pVoid) {
allocate_memory(size, pVoid, uiLine, szFileName);
}
return pVoid;
}
/*------------------------------------------------------------------------*/
/** Print a report of memory events to file. */
void CU_dump_memory_usage(const char* szFilename)
{
char* szDumpFileName = (char*)f_szDefaultDumpFileName;
unsigned int nValid;
unsigned int nInvalid;
PMEMORY_NODE pTempNode = NULL;
PMEMORY_EVENT pTempEvent = NULL;
FILE* pFile = NULL;
time_t tTime = 0;
/* use the specified file name, if supplied) */
if ((NULL != szFilename) && strlen(szFilename) > 0) {
szDumpFileName = (char*)szFilename;
}
if (NULL == (pFile = fopen(szDumpFileName, "w"))) {
fprintf(stderr, "Failed to open file \"%s\" : %s", szDumpFileName, strerror(errno));
return;
}
setvbuf(pFile, NULL, _IONBF, 0);
fprintf(pFile, "<\?xml version=\"1.0\" \?>");
fprintf(pFile, "\n<\?xml-stylesheet type=\"text/xsl\" href=\"Memory-Dump.xsl\" \?>");
fprintf(pFile, "\n<!DOCTYPE MEMORY_DUMP_REPORT SYSTEM \"Memory-Dump.dtd\">");
fprintf(pFile, "\n<MEMORY_DUMP_REPORT>");
fprintf(pFile, "\n <MD_HEADER/>");
fprintf(pFile, "\n <MD_RUN_LISTING>");
nValid = 0;
nInvalid = 0;
pTempNode = f_pMemoryTrackerHead;
while (NULL != pTempNode) {
fprintf(pFile, "\n <MD_RUN_RECORD>");
fprintf(pFile, "\n <MD_POINTER> %p </MD_POINTER>", pTempNode->pLocation);
fprintf(pFile, "\n <MD_EVENT_COUNT> %u </MD_EVENT_COUNT>", pTempNode->EventCount);
pTempEvent = pTempNode->pFirstEvent;
while (NULL != pTempEvent) {
fprintf(pFile, "\n <MD_EVENT_RECORD>");
fprintf(pFile, "\n <MD_SIZE> %u </MD_SIZE>", pTempEvent->Size);
fprintf(pFile, "\n <MD_ALLOC_FILE> %s </MD_ALLOC_FILE>", pTempEvent->AllocFilename);
fprintf(pFile, "\n <MD_ALLOC_LINE> %u </MD_ALLOC_LINE>", pTempEvent->AllocLine);
fprintf(pFile, "\n <MD_DEALLOC_FILE> %s </MD_DEALLOC_FILE>", pTempEvent->DeallocFilename);
fprintf(pFile, "\n <MD_DEALLOC_LINE> %u </MD_DEALLOC_LINE>", pTempEvent->DeallocLine);
fprintf(pFile, "\n </MD_EVENT_RECORD>");
if ((0 != pTempEvent->AllocLine) && (0 != pTempEvent->DeallocLine)) {
++nValid;
}
else {
++nInvalid;
}
pTempEvent = pTempEvent->pNext;
}
fprintf(pFile, "\n </MD_RUN_RECORD>");
pTempNode = pTempNode->pNext;
}
fprintf(pFile, "\n </MD_RUN_LISTING>");
fprintf(pFile, "\n <MD_SUMMARY>");
fprintf(pFile, "\n <MD_SUMMARY_VALID_RECORDS> %u </MD_SUMMARY_VALID_RECORDS>", nValid);
fprintf(pFile, "\n <MD_SUMMARY_INVALID_RECORDS> %u </MD_SUMMARY_INVALID_RECORDS>", nInvalid);
fprintf(pFile, "\n <MD_SUMMARY_TOTAL_RECORDS> %u </MD_SUMMARY_TOTAL_RECORDS>", nValid + nInvalid);
fprintf(pFile, "\n </MD_SUMMARY>");
time(&tTime);
fprintf(pFile, "\n <MD_FOOTER> Memory Trace for CUnit Run at %s </MD_FOOTER>", ctime(&tTime));
fprintf(pFile, "</MEMORY_DUMP_REPORT>");
fclose(pFile);
}
#endif /* MEMTRACE */
/** @} */
#ifdef CUNIT_BUILD_TESTS
#include "test_cunit.h"
/** Deactivate CUnit memory allocation
* After calling this function, all Cunit memory
* allocation routines will fail and return NULL.
*/
void test_cunit_deactivate_malloc(void)
{
f_bTestCunitMallocActive = CU_FALSE;
}
/** Activate CUnit memory allocation
* After calling this function, all Cunit memory
* allocation routines will behave normally (allocating
* memory if it is available).
*/
void test_cunit_activate_malloc(void)
{
f_bTestCunitMallocActive = CU_TRUE;
}
/** Retrieve the number of memory events recorded for a given pointer. */
unsigned int test_cunit_get_n_memevents(void* pLocation)
{
PMEMORY_NODE pNode = find_memory_node(pLocation);
return (pNode) ? pNode->EventCount : 0;
}
/** Retrieve the number of memory allocations recorded for a given pointer. */
unsigned int test_cunit_get_n_allocations(void* pLocation)
{
PMEMORY_NODE pNode = find_memory_node(pLocation);
PMEMORY_EVENT pEvent = NULL;
int result = 0;
if (NULL != pNode) {
pEvent = pNode->pFirstEvent;
while (NULL != pEvent) {
if (pEvent->AllocLine != NOT_ALLOCATED)
++result;
pEvent = pEvent->pNext;
}
}
return result;
}
/** Retrieve the number of memory deallocations recorded for a given pointer. */
unsigned int test_cunit_get_n_deallocations(void* pLocation)
{
PMEMORY_NODE pNode = find_memory_node(pLocation);
PMEMORY_EVENT pEvent = NULL;
int result = 0;
if (NULL != pNode) {
pEvent = pNode->pFirstEvent;
while (NULL != pEvent) {
if (pEvent->DeallocLine != NOT_DELETED)
++result;
pEvent = pEvent->pNext;
}
}
return result;
}
void test_CU_calloc(void)
{
void* ptr1 = NULL;
void* ptr2 = calloc(2, sizeof(int));
unsigned int n2 = test_cunit_get_n_memevents(ptr2);
/* test allocation failure */
test_cunit_deactivate_malloc();
ptr1 = CU_CALLOC(2, sizeof(int));
TEST(NULL == ptr1);
TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
test_cunit_activate_malloc();
/* normal allocation */
ptr1 = CU_CALLOC(2, sizeof(int));
TEST_FATAL(NULL != ptr1);
TEST(test_cunit_get_n_allocations(ptr1) != test_cunit_get_n_deallocations(ptr1));
TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
CU_FREE(ptr1);
TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
TEST(n2 == test_cunit_get_n_memevents(ptr2));
free(ptr2);
}
void test_CU_malloc(void)
{
void* ptr1 = NULL;
void* ptr2 = malloc(sizeof(int));
unsigned int n2 = test_cunit_get_n_memevents(ptr2);
/* test allocation failure */
test_cunit_deactivate_malloc();
ptr1 = CU_MALLOC(sizeof(int));
TEST(NULL == ptr1);
TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
test_cunit_activate_malloc();
/* normal allocation */
ptr1 = CU_MALLOC(sizeof(int));
TEST_FATAL(NULL != ptr1);
TEST(test_cunit_get_n_allocations(ptr1) != test_cunit_get_n_deallocations(ptr1));
TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
CU_FREE(ptr1);
TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
TEST(n2 == test_cunit_get_n_memevents(ptr2));
free(ptr2);
}
void test_CU_free(void)
{
/* covered by other test functions */
}
void test_CU_realloc(void)
{
void* ptr1 = CU_MALLOC(sizeof(int));
void* ptr2 = malloc(sizeof(int));
void* ptr3;
void* ptr4;
unsigned int n2 = test_cunit_get_n_memevents(ptr2);
/* test allocation failure */
test_cunit_deactivate_malloc();
ptr1 = CU_REALLOC(ptr1, sizeof(long int));
TEST(NULL == ptr1);
TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
test_cunit_activate_malloc();
/* normal allocation */
ptr3 = CU_MALLOC(sizeof(int));
TEST_FATAL(NULL != ptr3);
TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
TEST(test_cunit_get_n_allocations(ptr3) != test_cunit_get_n_deallocations(ptr3));
ptr4 = CU_REALLOC(ptr3, sizeof(long int));
TEST_FATAL(NULL != ptr4);
TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
if (ptr3 != ptr4)
TEST(test_cunit_get_n_allocations(ptr3) == test_cunit_get_n_deallocations(ptr3));
TEST(test_cunit_get_n_allocations(ptr4) != test_cunit_get_n_deallocations(ptr4));
CU_FREE(ptr4);
TEST(test_cunit_get_n_allocations(ptr1) == test_cunit_get_n_deallocations(ptr1));
TEST(test_cunit_get_n_allocations(ptr2) == test_cunit_get_n_deallocations(ptr2));
TEST(test_cunit_get_n_allocations(ptr3) == test_cunit_get_n_deallocations(ptr3));
TEST(test_cunit_get_n_allocations(ptr4) == test_cunit_get_n_deallocations(ptr4));
TEST(n2 == test_cunit_get_n_memevents(ptr2));
free(ptr2);
}
/** The main internal testing function for MyMem.c. */
void test_cunit_MyMem(void)
{
test_cunit_start_tests("MyMem.c");
test_CU_calloc();
test_CU_malloc();
test_CU_free();
test_CU_realloc();
test_cunit_end_tests();
}
#endif /* CUNIT_BUILD_TESTS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -