问题描述
- 【析构函数写法】如何使用析构函数释放类成员函数申请的堆内存
-
标题:【析构函数写法】如何使用析构函数释放类成员函数申请的堆内存环境:win7 64位/AMD CPU/C++ GCC4.7.2/Codeblocks
详细描述:如下所示”代码块1“,每次在调用encrypt()函数时均会申请一次内存,如何在析构函数中一次性销毁所有产生的内存,”代码块2“的方法不符合要求
扩展:如果上述问题无较好答案,是否有其他方法可以避免在类函数中使用new,但也能达到目的
代码块1:#include <iostream> #include <string.h> using namespace std; class cipher { public: char key[128]; cipher(const char *key_) { strcpy(key,key_); } char* encrypt(const char* text) { int a= (int((strlen(text)/128)+1))*128; //每运行一次则产生一个新内存 char *tempResult=new char[a]; strcpy(tempResult,text); strcat(tempResult,key); return tempResult; } ~cipher() { } }; int main() { const char* myKey="this is a key"; cipher encryptBook(myKey); const char* engilishBookContent="this is the content of the English book."; cout<<encryptBook.encrypt(engilishBookContent)<<endl; const char* chineseBookContent="this is the content of the Chinese book."; cout<<encryptBook.encrypt(chineseBookContent)<<endl; }
代码块2:
class cipher { public: char key[128]; char *tempResult; cipher(const char *key_) { strcpy(key,key_); tempResult = null; } char* encrypt(const char* text) { int a= (int((strlen(text)/128)+1))*128; if(tempResult != null){delete [] tempResult ;tempResult = null;} tempResult=new char[a]; strcpy(tempResult,text); strcat(tempResult,key); return tempResult; } ~cipher() { if(tempResult != null){delete [] tempResult ;tempResult = null;} } };
解决方案
#include <iostream>
#include <string.h>
using namespace std;
class cipher
{
public:
char key[128];
cipher(const char *key_)
{
strcpy(key,key_);
recordNew=NULL;//初始化指针数组
qtyRecord=0;//初始化指针数组的元素个数
}
char* encrypt(const char* text)
{
int a= (int((strlen(text)/128)+1))*128;
char *tempResult=new char[a];
strcpy(tempResult,text);
strcat(tempResult,key);
record(tempResult);
return tempResult;
}
void record(char *newChar)
{
cout<<"newChar=0X"<<hex<<(int)newChar<<endl;
char **tempP=new char* [qtyRecord+1];
//如果是第一次调用encrypt()函数,则直接赋值
//如果不是则需要先拷贝原指针成员后,再添加新建的指针
if (recordNew==NULL)
tempP[0]=newChar;
else
{
for (int i=0; i<=qtyRecord-1; ++i)
{
tempP[i]=recordNew[i];
cout<<"i="<<i<<" "<<"recordNew["<<i<<"]="<<hex<<(int)recordNew[i]<<endl;
}
tempP[qtyRecord]=newChar;
delete[] recordNew;//删除老的recordNew指针数组
}
recordNew=new char*[qtyRecord+1];
for(int j=0; j!=qtyRecord+1; ++j)
{
recordNew[j]=tempP[j];
cout<<"recordNew["<<j<<"]="<<"0x"<<hex<<(int)recordNew[j]<<endl;
}
++qtyRecord;//计数器加1
delete[] tempP;//删除临时指针数组
cout<<"****************************"<<endl;
}
~cipher()
{
if (recordNew==NULL) return;
delete[] recordNew;
}
//private:
char** recordNew;
int qtyRecord;
};
int main()
{
const char* myKey="this is a key";
cipher encryptBook(myKey);
const char* engilishBookContent="this is the content of the English book.";
encryptBook.encrypt(engilishBookContent);
// cout<<encryptBook.encrypt(engilishBookContent)<<endl;
const char* chineseBookContent="this is the content of the Chinese book.";
encryptBook.encrypt(chineseBookContent);
// cout<<encryptBook.encrypt(chineseBookContent)<<endl;
const char* mathBookContent="this is the content of the math book.";
encryptBook.encrypt(mathBookContent);
// cout<<encryptBook.encrypt(mathBookContent)<<endl;
const char* historyBookContent="this is the content of the history book.";
encryptBook.encrypt(historyBookContent);
// cout<<encryptBook.encrypt(historyBookContent)<<endl;
cout<<"++++++++++++++++++++++++++++"<<endl;
cout<<encryptBook.recordNew[1]<<endl;
encryptBook.~cipher();
cout<<encryptBook.recordNew[1]<<endl;
}
解决方案二:
http://blog.csdn.net/ljianhui/article/details/19649867
解决方案三:
一般来说,类的构造函数中可以申请内存与做一定的初始化工作;然后对应在析构函数做对应的内存释放与反初始化的动作。
但是,在一些编程规范中不建议在构造函数与析构函数中做这样的工作。建议的方法是实现一个 Init 与 Deinit 函数,在使用第一个调用 Init,最后一个调用 Deinit。
原因:类的全量变量,定义时就会执行构造函数。而此时程序还没有进入如Main 这样的入口;同样在程序结束时,由系统调用析构函数时,当析构函数出错就比较难分析。
解决方案四:
从函数的功能来看,你是想加工字符串, 但为什么不用string呢? 你可以将string&对象传进,类似这样
bool*encrypt(const char* text , string& stcString)
{
if(text==NULL)
return false;
stcString=text;
stcString+=key;
return true;
}
解决方案五:
从函数的功能来看,你是想加工字符串, 但为什么不用string呢? 你可以将string&对象传进,类似这样
bool*encrypt(const char* text , string& stcString)
{
if(text==NULL)
return false;
stcString=text;
stcString+=key;
return true;
}
解决方案六:
定义类成员变量 string m_strTempResult;
char* encrypt(const char* text)
{
m_strTempResult = text;
m_strTempResult.append(key);
return m_strTempResult.c_str();
}
解决方案七:
单独定义释放函数 在需要的地方调用来释放 比如析构函数
解决方案八:
关于在析构函数中释放内存
解决方案九:
可以外类中增加一个成员变量char *result;代替函数内的tempResult。在函数中动态申请result,然后在析构函数中释放result。