?? mymem.c
字號:
/* * CUnit - A Unit testing framework library for C. * Copyright (C) 2001 Anil Kumar * Copyright (C) 2004 Anil Kumar, Jerry St.Clair * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * Contains memory management functions used throughout CUnit project files. * * Created By : Anil Kumar on 13/Oct/2001 * Last Modified : 13/Oct/2001 * Comment : Moved some of the generic functions definitions * from other files to this one so as to use the * functions consitently. This file is not included * in the distribution headers because it is used * internally by CUnit. * EMail : aksaharan@yahoo.com * * Modified : 18-Jul-2004 (JDS) * Comment : New interface, doxygen comments, made local functions * & constants static, fixed reporting of memory tracking * (valid vs invalid cycles), restructured memory * tracking to detect reallocations & multiple deletions. * EMail : jds2@users.sourceforge.net * *//** @file * Memory management & reporting functions (implementation). *//** @addtogroup Framework @{*/#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <errno.h>#include <assert.h>#include <string.h>#include <time.h>#include "CUnit.h"#include "MyMem.h"#ifdef MEMTRACE#define MAX_FILE_NAME_LENGTH 256/** Name for memory dump file. */static const char* f_szDefaultDumpFileName = "CUnit-Memory-Dump.xml";#ifdef CUNIT_BUILD_TESTS/** For testing use (only) to simulate memory exhaustion - * if FALSE, allocation requests will always fail and return NULL. */static BOOL f_bTestCunitMallocActive = TRUE;#endif/** Structure holding the details of a memory allocation/deallocation event. */typedef struct mem_event { unsigned int Size; unsigned int AllocLine; char AllocFilename[MAX_FILE_NAME_LENGTH]; unsigned int DeallocLine; char DeallocFilename[MAX_FILE_NAME_LENGTH]; struct mem_event* pNext;} MEMORY_EVENT;typedef MEMORY_EVENT* PMEMORY_EVENT;#define NOT_ALLOCATED 0#define NOT_DELETED 0/** Structure holding the details of a memory node having allocation/deallocation events. */typedef struct mem_node { void* pLocation; unsigned int EventCount; PMEMORY_EVENT pFirstEvent; struct mem_node* pNext;} MEMORY_NODE;typedef MEMORY_NODE* PMEMORY_NODE;static PMEMORY_NODE f_pMemoryTrackerHead = NULL; /**< Head of double-linked list of memory nodes. */static unsigned int f_nMemoryNodes = 0; /**< Counter for memory nodes created. *//*------------------------------------------------------------------------*//** Locate the memory node for the specified memory location (returns NULL if none). */static PMEMORY_NODE find_memory_node(void* pLocation){ PMEMORY_NODE pMemoryNode = f_pMemoryTrackerHead; while (pMemoryNode) { if (pLocation == pMemoryNode->pLocation) break; pMemoryNode = pMemoryNode->pNext; } return pMemoryNode;}/*------------------------------------------------------------------------*//** Create a new memory node for the specified memory location. */static PMEMORY_NODE create_memory_node(void* pLocation){ PMEMORY_NODE pMemoryNode = NULL; PMEMORY_NODE pTempNode = NULL; /* a memory node for pLocation should not exist yet */ if (NULL == (pMemoryNode = find_memory_node(pLocation))) { pMemoryNode = malloc(sizeof(MEMORY_NODE)); assert(pMemoryNode && "Memory Allocation for new memory node failed in create_memory_node()."); pMemoryNode->pLocation = pLocation; pMemoryNode->EventCount = 0; pMemoryNode->pFirstEvent = NULL; pMemoryNode->pNext = NULL; /* add new node to linked list */ pTempNode = f_pMemoryTrackerHead; if (NULL == pTempNode) { f_pMemoryTrackerHead = pMemoryNode; } else { while (NULL != pTempNode->pNext) { pTempNode = pTempNode->pNext; } pTempNode->pNext = pMemoryNode; } ++f_nMemoryNodes; } return pMemoryNode;}/*------------------------------------------------------------------------*//** Add a new memory event having the specified parameters. */static PMEMORY_EVENT add_memory_event(PMEMORY_NODE pMemoryNode, int size, unsigned int alloc_line, const char* alloc_filename){ PMEMORY_EVENT pMemoryEvent = NULL; PMEMORY_EVENT pTempEvent = NULL; assert (pMemoryNode); pMemoryEvent = malloc(sizeof(MEMORY_EVENT)); assert(pMemoryEvent && "Memory Allocation for new memory event failed in create_memory_event()."); pMemoryEvent->Size = size; pMemoryEvent->AllocLine = alloc_line; strncpy(pMemoryEvent->AllocFilename, alloc_filename, MAX_FILE_NAME_LENGTH-1); pMemoryEvent->AllocFilename[MAX_FILE_NAME_LENGTH-1] = 0; pMemoryEvent->DeallocLine = NOT_DELETED; pMemoryEvent->DeallocFilename[0] = 0; pMemoryEvent->pNext = NULL; /* add new event to linked list */ pTempEvent = pMemoryNode->pFirstEvent; if (NULL == pTempEvent) { pMemoryNode->pFirstEvent = pMemoryEvent; } else { while (NULL != pTempEvent->pNext) { pTempEvent = pTempEvent->pNext; } pTempEvent->pNext = pMemoryEvent; } ++pMemoryNode->EventCount; return pMemoryEvent;}/*------------------------------------------------------------------------*//** Record memory allocation event. */static PMEMORY_NODE allocate_memory(int nSize, void* pLocation, unsigned int uiAllocationLine, const char* szAllocationFile){ PMEMORY_NODE pMemoryNode = NULL; /* attempt to locate an existing record for this pLocation */ pMemoryNode = find_memory_node(pLocation); /* pLocation not found - create a new event record */ if (NULL == pMemoryNode) pMemoryNode = create_memory_node(pLocation); /* add the new event record */ add_memory_event(pMemoryNode, nSize, uiAllocationLine, szAllocationFile); return pMemoryNode;}/*------------------------------------------------------------------------*//** Record memory deallocation event. */static void deallocate_memory(void* pLocation, unsigned int uiDeletionLine, const char* szDeletionFileName){ PMEMORY_NODE pMemoryNode = NULL; PMEMORY_EVENT pTempEvent = NULL; assert(uiDeletionLine); assert(szDeletionFileName); /* attempt to locate an existing record for this pLocation */ pMemoryNode = find_memory_node(pLocation); /* if no entry, then an unallocated pointer was freed */ if (NULL == pMemoryNode) { pMemoryNode = create_memory_node(pLocation); pTempEvent = add_memory_event(pMemoryNode, 0, NOT_ALLOCATED, ""); } else { /* there should always be at least 1 event for an existing memory node */ assert(pMemoryNode->pFirstEvent); /* locate last memory event for this pLocation */ pTempEvent = pMemoryNode->pFirstEvent; while (NULL != pTempEvent->pNext) pTempEvent = pTempEvent->pNext; /* if pointer has already been freed, create a new event for double deletion */ if (NOT_DELETED != pTempEvent->DeallocLine) pTempEvent = add_memory_event(pMemoryNode, pTempEvent->Size, NOT_ALLOCATED, ""); } pTempEvent->DeallocLine = uiDeletionLine; strncpy(pTempEvent->DeallocFilename, szDeletionFileName, MAX_FILE_NAME_LENGTH-1); pTempEvent->DeallocFilename[MAX_FILE_NAME_LENGTH-1] = 0;}/*------------------------------------------------------------------------*//** Custom calloc function with memory event recording. */void* CU_calloc(size_t nmemb, size_t size, unsigned int uiLine, const char* szFileName){ void* pVoid = NULL;#ifdef CUNIT_BUILD_TESTS if (!f_bTestCunitMallocActive) return NULL;#endif pVoid = calloc(nmemb, size); if (pVoid) allocate_memory(nmemb * size, pVoid, uiLine, szFileName); return pVoid;}/*------------------------------------------------------------------------*//** Custom malloc function with memory event recording. */void* CU_malloc(size_t size, unsigned int uiLine, const char* szFileName){ void* pVoid = NULL;#ifdef CUNIT_BUILD_TESTS if (!f_bTestCunitMallocActive) return NULL;#endif pVoid = malloc(size); if (pVoid) allocate_memory(size, pVoid, uiLine, szFileName); return pVoid;}/*------------------------------------------------------------------------*//** Custom free function with memory event recording. */void CU_free(void *ptr, unsigned int uiLine, const char* szFileName){ deallocate_memory(ptr, uiLine, szFileName); free(ptr);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -