2 yokeyoke yokeyoke 于 2016.01.15 23:06 提问

【析构函数写法】如何使用析构函数释放类成员函数申请的堆内存

标题:【析构函数写法】如何使用析构函数释放类成员函数申请的堆内存

环境: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;}
    }

};

9个回答

yokeyoke
yokeyoke   2016.01.19 20:45
已采纳
 #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;
}

caozhy
caozhy   Ds   Rxr 2016.01.16 00:08
91program
91program   Ds   Rxr 2016.01.16 11:11

一般来说,类的构造函数中可以申请内存与做一定的初始化工作;然后对应在析构函数做对应的内存释放与反初始化的动作。
但是,在一些编程规范中不建议在构造函数与析构函数中做这样的工作。建议的方法是实现一个 Init 与 Deinit 函数,在使用第一个调用 Init,最后一个调用 Deinit。

原因:类的全量变量,定义时就会执行构造函数。而此时程序还没有进入如Main 这样的入口;同样在程序结束时,由系统调用析构函数时,当析构函数出错就比较难分析。

weikanzong
weikanzong   2016.01.16 21:27

从函数的功能来看,你是想加工字符串, 但为什么不用string呢? 你可以将string&对象传进,类似这样

 bool*encrypt(const char* text , string& stcString)
    {
        if(text==NULL)
                    return false;
                stcString=text;
                stcString+=key;
        return true;
    }

weikanzong
weikanzong   2016.01.16 21:28

从函数的功能来看,你是想加工字符串, 但为什么不用string呢? 你可以将string&对象传进,类似这样

 bool*encrypt(const char* text , string& stcString)
    {
        if(text==NULL)
                    return false;
                stcString=text;
                stcString+=key;
        return true;
    }

shuizhonghan
shuizhonghan   2016.01.19 18:38

定义类成员变量 string m_strTempResult;
char* encrypt(const char* text)
{
m_strTempResult = text;
m_strTempResult.append(key);
return m_strTempResult.c_str();
}

oyljerry
oyljerry   Ds   Rxr 2016.01.16 09:01

单独定义释放函数 在需要的地方调用来释放 比如析构函数

CSDNXIAOD
CSDNXIAOD   2016.01.15 23:08

关于在析构函数中释放内存
----------------------biu~biu~biu~~~在下问答机器人小D,这是我依靠自己的聪明才智给出的答案,如果不正确,你来咬我啊!

Le_temps
Le_temps   2016.01.15 23:24

可以外类中增加一个成员变量char *result;代替函数内的tempResult。在函数中动态申请result,然后在析构函数中释放result。

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!