内存开销记录模块

43 篇文章 0 订阅

利用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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿木小呆呆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值