利用hash表来记录 在程序中malloc和free内存的情况
MemoryManage.h
#ifndef _MEMORYMANAGE_H_
#define _MEMORYMANAGE_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NODE_NUM (15)
#define FILE_NAME_STR (120)
#define HASH_KEY_STR (32)
#define Debug_Printf(fmt,...) printf("debug: [file:%s line:%d] "fmt,__FILE__,__LINE__,##__VA_ARGS__)
#define Error_Printf(fmt,...) printf("error: [file:%s line:%d] "fmt,__FILE__,__LINE__,##__VA_ARGS__)
extern void* HashTable_Malloc(size_t p_pSize, char *p_pFile, int p_nLine, char *p_pFun);
extern void HashTable_Free(void* p_pMemoryAdress);
#define MALLOC(size) HashTable_Malloc(size, __FILE__, __LINE__, __FUNCDNAME__)
#define FREE(p) HashTable_Free(p)
typedef struct Hash_Node_t
{
int m_nKey;
int m_nMemorySize; /*malloc的内存大小*/
void *m_pMemoryAddress;
char m_szFileName[FILE_NAME_STR]; /*那个文件哪一行进行的malloc*/
struct Hash_Node_t *m_pObjNextNode; /*当发生碰撞时,向后存储*/
}Hash_Node;
extern int HashTable_Init( );
extern void HashTable_Printf( );
#endif
MemoryManage.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "MemoryManage.h"
#define SN_SUCCESS (0)
#define SN_ERROR (-1)
static Hash_Node *objAllHashNode[MAX_NODE_NUM] = { 0 };
int HashTable_Init( )
{
for(int i = 0; i < MAX_NODE_NUM; ++i)
{
objAllHashNode[i] = (Hash_Node *)malloc(sizeof(Hash_Node));
if(!objAllHashNode[i])
{
return SN_ERROR;
}
memset(objAllHashNode[i], 0, sizeof(Hash_Node));
}
return SN_SUCCESS;
}
int HashTable_Ch2Int(char p_cCh)
{
if((p_cCh >= '0') && (p_cCh <= '9'))
{
return p_cCh - '0';
}
else if((p_cCh >= 'A') && (p_cCh <= 'F'))
{
return p_cCh - 'A' + ('9' - '0' + 1);
}
return 0;
}
unsigned int HashTable_Str2HashVal(const char* p_pStr)
{
unsigned char *pTempStr = (unsigned char*)p_pStr;
unsigned int nHash = 0;
float nSeed = 3;//3,5,7,9,...,etc奇数,系数取大于1的奇数,可以有效避免碰撞
float nIndex = 0;
float nLen = strlen((char*)pTempStr);
while( *pTempStr )
{
nHash = nHash + pow(nSeed,nLen-nIndex-1)*(*pTempStr);
++pTempStr;
nIndex++;
}
return nHash%MAX_NODE_NUM;
}
/*计算key值*/
int HashTable_Get_Key(Hash_Node *p_pObjNodeInfo)
{
if(!p_pObjNodeInfo)
{
Error_Printf("HashTable_Get_Key Failed, Hash_Node is Null !!!\n");
return SN_ERROR;
}
char szStr[HASH_KEY_STR] = { 0 };
_snprintf(szStr, HASH_KEY_STR, "%p", p_pObjNodeInfo->m_pMemoryAddress);
int nStrLen = strlen(szStr);
return HashTable_Str2HashVal(szStr);
}
/*插入*/
int HashTable_Insert(Hash_Node *p_pObjNodeInfo)
{
if(!p_pObjNodeInfo)
{
Error_Printf("HashTable_Insert Failed, Hash_Node is Null !!!\n");
return SN_ERROR;
}
Hash_Node *objNode = NULL;
Hash_Node *objNewNode = NULL;
int nKey = HashTable_Get_Key(p_pObjNodeInfo);
if(nKey <= SN_ERROR)
{
Error_Printf("HashTable_Insert Err !!\n");
return SN_ERROR;
}
if(nKey <= MAX_NODE_NUM)
{
objNode = objAllHashNode[nKey];
if(!objNode)
{
Error_Printf("Hash Table Anomalous, objHashNode[nKey] is Null nKey = %d !!!\n", nKey);
return SN_ERROR;
}
/*把数据放入链表尾部*/
{
/*找到链表尾部*/
while(objNode->m_pObjNextNode != NULL)
{
objNode = objNode->m_pObjNextNode;
}
/*申请空间接入到尾部*/
objNewNode = (Hash_Node *)malloc(sizeof(Hash_Node));
if(!objNewNode)
{
Error_Printf("%s %d :malloc objNewNode Failed !!!\n", __FILE__, __LINE__);
return SN_ERROR;
}
memset(objNewNode, 0, sizeof(Hash_Node));
objNode->m_pObjNextNode = objNewNode;
objNode = objNode->m_pObjNextNode;
}
objNode->m_nKey = nKey;
objNode->m_nMemorySize = p_pObjNodeInfo->m_nMemorySize;
objNode->m_pMemoryAddress = p_pObjNodeInfo->m_pMemoryAddress;
memcpy(objNode->m_szFileName, p_pObjNodeInfo->m_szFileName, strlen(p_pObjNodeInfo->m_szFileName));
Debug_Printf("HashTable_Insert Success !!!\n");
}
else
{
Error_Printf("Invilad Key(%d)\n", nKey);
}
return SN_SUCCESS;
}
/*删除*/
int HashTable_Delete(Hash_Node *p_pObjNodeInfo)
{
Hash_Node *objNode = NULL;
if(!p_pObjNodeInfo)
{
Error_Printf("HashTable_Delete Failed, Hash_Node is Null !!!\n");
return SN_ERROR;
}
if(!p_pObjNodeInfo->m_pMemoryAddress)
{
Error_Printf("HashTable_Delete Failed, m_pMemoryAddress is Null !!!\n");
return SN_ERROR;
}
int nKey = HashTable_Get_Key(p_pObjNodeInfo);
if(nKey <= SN_ERROR)
{
Error_Printf("HashTable_Get_Key Err !!\n");
return SN_ERROR;
}
objNode = objAllHashNode[nKey];
if(!objNode)
{
Error_Printf("Hash Table Anomalous, objHashNode[nKey] is Null nKey = %d !!!\n", nKey);
return SN_ERROR;
}
/*匹配节点*/
while(objNode->m_pObjNextNode != NULL)
{
if(objNode->m_pObjNextNode->m_pMemoryAddress == p_pObjNodeInfo->m_pMemoryAddress)
{
Hash_Node *objTempNode = objNode->m_pObjNextNode->m_pObjNextNode;
/*删除匹配到的节点*/
free(objNode->m_pObjNextNode);
objNode->m_pObjNextNode = objTempNode;
break;
}
objNode = objNode->m_pObjNextNode;
}
return SN_SUCCESS;
}
void* HashTable_Malloc(size_t p_pSize, char *p_pFile, int p_nLine, char *p_pFun)
{
Hash_Node objHashNode;
void* pMemory = malloc(p_pSize);
memset(&objHashNode, 0, sizeof(Hash_Node));
objHashNode.m_nMemorySize = p_pSize;
objHashNode.m_pMemoryAddress = pMemory;
_snprintf(objHashNode.m_szFileName, FILE_NAME_STR,"file:%s line:%d fun:%s", p_pFile, p_nLine, p_pFun);
HashTable_Insert(&objHashNode);
return pMemory;
}
void HashTable_Free(void* p_pMemoryAdress)
{
Hash_Node objHashNode;
if(!p_pMemoryAdress)
{
Error_Printf("Release a null pointer\n");
}
memset(&objHashNode, 0, sizeof(Hash_Node));
objHashNode.m_pMemoryAddress = p_pMemoryAdress;
HashTable_Delete(&objHashNode);
return free(p_pMemoryAdress);
}
/*打印当前内存情况*/
void HashTable_Printf( )
{
Hash_Node *objHashNode = NULL;
for(int i = 0; i < MAX_NODE_NUM; ++i)
{
objHashNode = objAllHashNode[i];
if(objHashNode)
{
while(objHashNode->m_pObjNextNode)
{
Debug_Printf("Key: %d\n", objHashNode->m_pObjNextNode->m_nKey);
Debug_Printf("size: %d\n", objHashNode->m_pObjNextNode->m_nMemorySize);
Debug_Printf("MemoryAddress: %p\n", objHashNode->m_pObjNextNode->m_pMemoryAddress);
Debug_Printf("%s\n", objHashNode->m_pObjNextNode->m_szFileName);
objHashNode = objHashNode->m_pObjNextNode;
}
}
}
}
main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MemoryManage.h"
int main( )
{
char *pStr[10] = { 0 };
HashTable_Init();
for(int i = 0; i < 10; ++i)
{
pStr[i] = (char *)MALLOC(1);
}
HashTable_Printf();
for(int i = 0; i < 10; ++i)
{
FREE(pStr[i]);
}
HashTable_Printf();
return 0;
}