We had a requirements of dynamic memory allocation, but the issue associated with dynamic memory allocation is memory leaks, forget to release memory or exception prevent the execution of memory allocation code. So a template based class is created to allocate memory dynamically in constructor and release it on destructor. The main thing is to create it's local variable on stack and supply the variable memory size in constructor, being the local variable on stack will guarantee cause execution of destructor (which will result in deallocation of memory) so no worries of releasing of memory or exceptions.
It is noted that we usually need char buffer, so the default template type is char.
To have deep copy in place, copy constructor and assignment operator are implemented.
The code is as follows:
#pragma once
#include "iostream"
using namespace std;
typedef unsigned char UCHAR8;
template
class CDataBuf
{
private:
int m_Len;
T *m_Buf;
void init(int len);
public:
CDataBuf(void);
CDataBuf(int len) { init(len); }
~CDataBuf(void);
CDataBuf(CDataBuf &dataBuf);
CDataBuf &operator=(CDataBuf &dataBuf);
T *GetBuf() { return m_Buf; }
int GetLen() { return m_Len; }
};
template
void CDataBuf::init(int len) {
try {
this->m_Len = len;
m_Buf = new T[len];
memset(m_Buf, 0, len * sizeof(T));
}
catch( exception *exc ) {
char tmpBuf[255];
sprintf(tmpBuf, "error can not alloc memory (%s)", exc->what());
Log(tmpBuf, LogLevelError);
throw tmpBuf;
}
catch( char *exc ) {
char tmpBuf[255];
sprintf(tmpBuf, "error can not alloc memory (%s)", exc);
Log(tmpBuf, LogLevelError);
throw tmpBuf;
}
catch( ... ) {
char *tmpBuf="unknown error occured";
Log(tmpBuf, LogLevelError);
throw tmpBuf;
}
}
template
CDataBuf::~CDataBuf(void) {
if(m_Buf) {
delete[] m_Buf;
m_Buf=0;
m_Len=0;
}
}
#include "StdAfx.h"
#include "DataBuf.h"
template
CDataBuf::CDataBuf(void) {
m_Buf=0;
m_Len=0;
}
template
CDataBuf::CDataBuf(CDataBuf &dataBuf) {
init(dataBuf.m_Len);
memcpy(this->m_Buf, dataBuf.m_Buf, dataBuf.m_Len * sizeof(T));
}
template
CDataBuf &CDataBuf::operator=(CDataBuf &dataBuf) {
if(m_Buf) {
delete[] m_Buf;
m_Len = 0;
}
init(dataBuf.m_Len);
memcpy(this->m_Buf, dataBuf.m_Buf, dataBuf.m_Len * sizeof(T));
return *this;
}
It is noted that we usually need char buffer, so the default template type is char.
To have deep copy in place, copy constructor and assignment operator are implemented.
The code is as follows:
#pragma once
#include "iostream"
using namespace std;
typedef unsigned char UCHAR8;
template
class CDataBuf
{
private:
int m_Len;
T *m_Buf;
void init(int len);
public:
CDataBuf(void);
CDataBuf(int len) { init(len); }
~CDataBuf(void);
CDataBuf(CDataBuf &dataBuf);
CDataBuf &operator=(CDataBuf &dataBuf);
T *GetBuf() { return m_Buf; }
int GetLen() { return m_Len; }
};
template
void CDataBuf::init(int len) {
try {
this->m_Len = len;
m_Buf = new T[len];
memset(m_Buf, 0, len * sizeof(T));
}
catch( exception *exc ) {
char tmpBuf[255];
sprintf(tmpBuf, "error can not alloc memory (%s)", exc->what());
Log(tmpBuf, LogLevelError);
throw tmpBuf;
}
catch( char *exc ) {
char tmpBuf[255];
sprintf(tmpBuf, "error can not alloc memory (%s)", exc);
Log(tmpBuf, LogLevelError);
throw tmpBuf;
}
catch( ... ) {
char *tmpBuf="unknown error occured";
Log(tmpBuf, LogLevelError);
throw tmpBuf;
}
}
template
CDataBuf::~CDataBuf(void) {
if(m_Buf) {
delete[] m_Buf;
m_Buf=0;
m_Len=0;
}
}
#include "StdAfx.h"
#include "DataBuf.h"
template
CDataBuf::CDataBuf(void) {
m_Buf=0;
m_Len=0;
}
template
CDataBuf::CDataBuf(CDataBuf &dataBuf) {
init(dataBuf.m_Len);
memcpy(this->m_Buf, dataBuf.m_Buf, dataBuf.m_Len * sizeof(T));
}
template
CDataBuf &CDataBuf::operator=(CDataBuf &dataBuf) {
if(m_Buf) {
delete[] m_Buf;
m_Len = 0;
}
init(dataBuf.m_Len);
memcpy(this->m_Buf, dataBuf.m_Buf, dataBuf.m_Len * sizeof(T));
return *this;
}
No comments:
Post a Comment