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