📄 memrecord.h
字号:
/**
* file : MemRecord.h
* comment :
*
*/
#ifndef MemRecord_h
#define MemRecord_h 1
#include <map>
#include <list>
#include <stack>
#include <pthread.h>
#include <sys/wait.h>
#include "Header.h"
#include "CommonMutex.h"
using namespace std;
#define SINGLE_NEW 0x00 // indicate alloc memory with new type
#define ARRAY_NEW 0x01 // indicate alloc memory with new[] type
#define SINGLE_DELETE 0x02 // indicate free memory with delete type
#define ARRAY_DELETE 0x03 // indicate free memory with delete[] type
#define FILENAME_LENGTH 32 // the filename length
#define MEMORY_INFO 0X12345678 // indicate the message type on the message queue
typedef struct
{
char Filename[ FILENAME_LENGTH ]; // new所在的源程序文件名
unsigned long LineNum; // new在源文件中的行号
size_t AllocSize; // 分配的内存大小
int OperationType;
void * pBuffer; // 分配后得到的内存指针
short errCode; // 0 - 没有释放, 1 - delete了new[]分配的内存
}MemOperation;
typedef struct
{
int Type; // message type, in this module must be MEMORY_INFO
MemOperation Data; // content of memory operation
} MsgBuffer;
#if defined( MEM_DEBUG )
class MemRecord
{
public:
/**
* 函数名称: MemRecord
* 函数功能: 初始化类的数据成员(创建消息队列)
* @param:
* @return:
* @see:
*/
MemRecord();
/**
* 函数名称: ~MemRecord
* 函数功能: 打印m_mapMemory&m_listMemory中的内存
* 删除消息队列
* @param:
* @return:
* @see:
*/
virtual ~MemRecord();
/**
* 函数名称: Insert
* 函数功能: 将一次内存操作插入到映射表(m_mapMemory)中
* @param: pBuffer - 分配成功的内存指针, 作为映射表的键值
* @param: pRecord - 内存操作的情况(包括文件名, 行号, 分配大小, 分配方式等)
* @return:
* @see: Erase
*/
void Insert( void *pBuffer, MemOperation *pRecord );
/**
* 函数名称: Erase
* 函数功能: 对m_mapMemory中的相应记录进行删除
* @param: pBuffer - 所要删除的内存指针
* @return: pRecord - delete的具体情况(包括文件名, 行号, 分配大小, 删除方式等)
* @see: Insert
*/
int Erase( void *pBuffer, MemOperation *pRecord );
/**
* 函数名称: GetMsgQueue
* 函数功能: 取得该类所创建的消息队列号
* @param: 无
* @return: 消息队列标识号
* @see:
*/
int GetMsgQueue() { return m_nMsgQueue; }
/**
* 函数名称: GetMsgFilePath
* 函数功能: 取得建立消息队列所用到的文件名
* @param: path - 存放所取得的文件名
* @return:
* @see:
*/
void GetMsgFilePath( char *path );
/**
* 函数名称: GetMainProcessPid
* 函数功能: 取得被检测进程pid
* @param: 无
* @return: 被检测进程pid
* @see:
*/
pid_t GetMainProcessPid() {return m_pidMain;};
private:
/**
* Record the memory alloc, use the pointer from new operator success alloction as the key value of
* map data structor
*
* After exit the main() function, the result of memory leak will be output to a file named "leak.rec"
* that exist on the directory with execute file. if the file exist, it will truncate the length to zero.
*/
map<void *, MemOperation> m_mapMemory;
list<MemOperation> m_listMemory; // save the ErrorDelete(the way of new and delete is not matching) information.
/**
* gurantee that synchronized operation of the m_mapMemory and m_listMemory
*/
CCommonMutex m_mutexRecord;
/**
* indicate the message queue
*/
int m_nMsgQueue;
/**
*
*/
char m_szMsgPath[ 64 ];
pid_t m_pidMain;
};
/**
* 在delete operator发生递归调用的时候,对前一次的delete operator调用所
* 产生的文件名和行号进行现场保留。
*/
typedef struct
{
char Filename[ FILENAME_LENGTH ]; //
unsigned long LineNum; //
}DELINFOSTACK;
#define THIS_FILE __FILE__
void* operator new( size_t nSize, char* pszFileName, int nLineNum );
void* operator new[]( size_t nSize, char* pszFileName, int nLineNum );
void operator delete( void *ptr );
void operator delete[]( void *ptr );
void InterruptHandler( int signo );
#define DEBUG_NEW new( THIS_FILE, __LINE__ )
extern char DELETE_FILE[ FILENAME_LENGTH ];
extern int DELETE_LINE;
extern void BuildStack();
/**
* 原来用的是POSIX中的pthread_mutex_t, 当时pthread_mutex_t
* 在同一线程重入时会造成死锁, 现在换成CCommonMutex类型(2003/05/13)
*/
extern CCommonMutex globalLock;
// if the DELETE_LINE is not 0, it means we need keep the older
// info in mind for subsequence call.
#define DEBUG_DELETE globalLock.Lock(); \
if (DELETE_LINE != 0) BuildStack();\
strncpy( DELETE_FILE, __FILE__,FILENAME_LENGTH - 1 ); \
DELETE_FILE[ FILENAME_LENGTH - 1 ]= '\0'; \
DELETE_LINE = __LINE__; \
delete
#else
class MemRecord {};
#endif // end defined( MEM_DEBUG )
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -