一般程序里面内存申请的部分还是很多的(例如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.csdn.net/lulixue/article/details/1478443