一般程序里面内存申请的部分还是很多的(例如malloc,free,new,delete等),然而如果需要申请2维到多维的数组,以及错误处理时,就需要在每一处调用内存申请函数处加入相应的错误处理代码。这样的代码编写效率会比较低下。然而使用宏也有不方便的地方。所以自己写了一个简单带日志的内存申请和释放的类(LogMemory)。
LogMemory主要有如下功能:
1)申请释放内存,并且带有日志输出。其中日志使用了log4cplus。
2)申请释放2维和3维的数组。
LogMemory.h
class LOGMEMORY_EXPORT LogMemory
{
public:
LogMemory(void);
~LogMemory(void);
private:
static log4cplus::Logger memLogger;
public:
static void initLog(void);
static void* Lmalloc(size_t size,const char* file,int line);
static void* Lcalloc(size_t numOfElements,size_t sizeOfElements,const char* file,int line);
static void Lfree(void* mem,const char* file,int line);
static void ** Lcalloc_2d( size_t d1, size_t d2, size_t sizeOfElements,
const char* file, int line);
static void Lfree_2d(void **mem,const char *file, int line);
static void*** Lcalloc_3d( size_t d1, size_t d2, size_t d3, size_t sizeOfElements,
const char* file, size_t line);
static void Lfree_3d(void ***mem,const char *file, int line);
};
LogMemory.cpp
#include "LogMemory.h"
using namespace log4cplus;
using namespace std;
#define WITH_FILE_LINE " file:" <<file<<"("<<dec<<line<<")"
LogMemory::LogMemory(void)
{
}
LogMemory::~LogMemory(void)
{
}
Logger LogMemory::memLogger=Logger::getInstance(LOG4CPLUS_TEXT("Memorylog"));
void LogMemory::initLog(void)
{
/* Instantiate an appender object */
SharedAppenderPtr _append(new FileAppender(LOG4CPLUS_TEXT("Memory.log")));
_append->setName(LOG4CPLUS_TEXT("file log test"));
/*Attach the appender object to the logger */
memLogger.addAppender(_append);
}
void* LogMemory::Lmalloc(size_t size,const char* file,int line)
{
void* mem = malloc(size);
LOG4CPLUS_DEBUG(memLogger, "malloc size:"<<size<<" Bytes,address:0x"<<hex<<mem<<WITH_FILE_LINE);
if ( NULL == mem )
{
LOG4CPLUS_ERROR(memLogger, "malloc size:"<<size<<" fail!"<<WITH_FILE_LINE) ;
return NULL;
}
return mem;
}
void* LogMemory::Lcalloc(size_t numOfElements,size_t sizeOfElements,const char* file,int line)
{
void* mem = calloc(numOfElements,sizeOfElements);
LOG4CPLUS_DEBUG(memLogger,
"calloc count:"<< numOfElements<<" elementSize:"<<sizeOfElements<<" Bytes,address:0x"<<hex<<mem<<WITH_FILE_LINE);
if ( NULL == mem )
{
LOG4CPLUS_ERROR(memLogger,
"calloc count:"<< numOfElements<<" elementSize:"<<sizeOfElements<<" fail!"<<WITH_FILE_LINE);
return NULL;
}
return mem;
}
void LogMemory::Lfree(void* mem,const char* file,int line)
{
if ( NULL == mem )
{
LOG4CPLUS_WARN(memLogger, "This is a int: "<<hex << mem <<WITH_FILE_LINE) ;
return;
}
free(mem);
LOG4CPLUS_DEBUG(memLogger, "free memory address:"<<hex<<mem <<WITH_FILE_LINE);
}
void ** LogMemory::Lcalloc_2d ( size_t d1, size_t d2, size_t sizeOfElements,
const char *file, int line)
{
char **ref, *mem;
size_t i, offset;
mem = (char *) Lcalloc(d1*d2, sizeOfElements, file, line);
ref = (char **) Lmalloc(d1 * sizeof(void *), file, line);
for (i = 0, offset = 0; i < d1; i++, offset += d2*sizeOfElements)
ref[i] = mem + offset;
return ((void **) ref);
}
void LogMemory::Lfree_2d(void **mem,const char *file, int line)
{
if (mem) Lfree(mem[0], file, line);
Lfree(mem, file, line);
}
void*** LogMemory::Lcalloc_3d(size_t d1, size_t d2, size_t d3, size_t sizeOfElements,
const char *caller_file, size_t caller_line)
{
char ***ref1, **ref2, *mem;
size_t i, j, offset;
mem = (char *) Lcalloc(d1*d2*d3, sizeOfElements, caller_file, caller_line);
ref1 = (char ***) Lmalloc(d1 * sizeof(void **), caller_file, caller_line);
ref2 = (char **) Lmalloc(d1*d2 * sizeof(void *), caller_file, caller_line);
for (i = 0, offset = 0; i < d1; i++, offset += d2)
ref1[i] = ref2+offset;
offset = 0;
for (i = 0; i < d1; i++) {
for (j = 0; j < d2; j++) {
ref1[i][j] = mem + offset;
offset += d3*sizeOfElements;
}
}
return ((void ***) ref1);
}
void LogMemory::Lfree_3d(void ***mem,const char *file, int line)
{
if (mem && mem[0]) Lfree(mem[0][0], file, line);
if (mem) Lfree(mem[0], file, line);
Lfree(mem, file, line);
}
test.cpp
#include "LogMemory.h"
int main()
{
int* a=NULL;
LogMemory::initLog();
a = (int *) log_malloc(10*sizeof(int));
log_free(a);
a = (int*)log_calloc(10,sizeof(int));
log_free(a);
float** b=NULL;
b = (float**) log_calloc_2d(3,4,sizeof(float));
for (int i=0;i<3;i++)
{
for (int j=0;j<4;j++)
{
b[i][j] = (float)1.2*(i+j);
printf("%f\t",b[i][j]);
}
printf("\n");
}
log_free_2d((void**)b);
return 0;
}
运行test.cpp后生成一个memory.log的文件,内容如下:
DEBUG - malloc size:40 Bytes,address:0x003D83E8 file:d:\我的文档\visual studio 2008\projects\logmemory\logmemorytest\test.cpp(7)
DEBUG - free memory address:003D83E8 file:d:\我的文档\visual studio 2008\projects\logmemory\logmemorytest\test.cpp(9)
DEBUG - calloc count:10 elementSize:4 Bytes,address:0x003D83E8 file:d:\我的文档\visual studio 2008\projects\logmemory\logmemorytest\test.cpp(10)
DEBUG - free memory address:003D83E8 file:d:\我的文档\visual studio 2008\projects\logmemory\logmemorytest\test.cpp(11)
DEBUG - calloc count:12 elementSize:4 Bytes,address:0x003D8658 file:d:\我的文档\visual studio 2008\projects\logmemory\logmemorytest\test.cpp(14)
DEBUG - malloc size:12 Bytes,address:0x003D83E8 file:d:\我的文档\visual studio 2008\projects\logmemory\logmemorytest\test.cpp(14)
DEBUG - free memory address:003D8658 file:d:\我的文档\visual studio 2008\projects\logmemory\logmemorytest\test.cpp(15)
DEBUG - free memory address:003D83E8 file:d:\我的文档\visual studio 2008\projects\logmemory\logmemorytest\test.cpp(15)
Reference:
(1)the log4cplus project:http://log4cplus.sourceforge.net/index.html
(2)log4cplus库(一)(简单使用):http://www.cppblog.com/API/archive/2011/04/02/143275.html
(3)开源日志系统 - log4cplus (一):http://blog.youkuaiyun.com/lulixue/article/details/1478443