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

问题描述

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

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

环境: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。

时间: 2024-07-31 11:31:58

c++-【析构函数写法】如何使用析构函数释放类成员函数申请的堆内存的相关文章

c++中string类成员函数c_str()的用法_C 语言

1.string类成员函数c_str()的原型: const char *c_str()const;//返回一个以null终止的c字符串 2.c_str()函数返回一个指向正规c字符串的指针,内容和string类的本身对象是一样的,通过string类的c_str()函数能够把string对象转换成c中的字符串的样式; 3.操作c_str()函数的返回值时,只能使用c字符串的操作函数,如:strcpy()等函数.因为,string对象可能在使用后被析构函数释放掉,那么你所指向的内容就具有不确定性.

【C/C++学院】(8)全局函数和类成员函数转化/友元/操作符重载

1.全局函数和类成员函数转化     全局函数和成员函数的相互转化:只需要修改一个指向本类的this指针: #include <iostream> using namespace std; class Test { public: Test(int a, int b) { this->a = a; this->b = b; } //成员函数 Test &Gadd2(Test &t2) { this->a = this->a + t2.a; this-&g

C#想方设法调用C++类成员函数!

问题描述 .net互操作一直没有接触过,最近有一个C#程序必须要使用C++DLL类成员函数.....头都木了,各种狂查,基本对Pinvoke有一些了解.但第一次看到PInvoke声明DLL函数的写法"staticextern"时,就有疑问:这个static,难道意味着C++DLL函数都必须是全局的?想调用C++public类成员函数是行不通的?于是写了个测试程序,发现PInvoke貌似调不了C++类成员函数..........但由于本人没有此方面任何经验,无法做结论,所以请教各位:PI

谈函数指针(全局/类成员函数)和函数对象

函数指针(全局函数/类成员函数).函数对象(Function object) 一. 函数指针类型为全局函数. #include "stdafx.h"#include <iostream>using namespace std;class TestAction;typedef void (*fp)(int); void Drink(int i){ cout<<"No. "<<i<<" drink..."

直接调用类成员函数地址

一.成员函数指针的用法 在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一个地址,在需要的时候可以任意转换并直接调用.但对成员函数来说,常规类型转换是通不过编译的,调用的时候也必须采用特殊的语法.C++专门为成员指针准备了三个运算符: "::*"用于指针的声明,而"->*"和".*"用来调用指针指向的函数.比如: class tt { public: void foo(int x){ printf("\

类成员函数作为多线程的入口函数如何访问对话框资源

问题描述 类成员函数作为多线程的入口函数如何访问对话框资源 我申请了一个类成员函数作为多线程的入口函数,如何在该函数中访问对话框资源(分割后的对话框) 解决方案 需要把类的实例作为线程函数参数传递进去.

c++,关于类成员函数作为线程的入口函数

问题描述 c++,关于类成员函数作为线程的入口函数 class Map {public: Bird *pB; Pig *pP; ..........}class Grav {public: Map *pM; ...... void runBird(Bird &b); void runPig(Pig &p); void run(Map &m);}void Grav::run(Map &m) { thread t[2]; t[0] = thread(&Grav::run

c++基础-为什么不合法,基类的类成员函数在最下面定义

问题描述 为什么不合法,基类的类成员函数在最下面定义 解决方案 是不是有些变量在上面已经定义过了. 解决方案二: 把错误粘出来看一下吧~ 解决方案三: 函数定义跟申明的原型是否一致 解决方案四: #include 了么? 解决方案五: include fstream了么? 解决方案六: if(xxx){....}; if需要"{}"的吧... 解决方案七: 另外没有判断shape[]的大小,如果shape[]小于4,就溢出了.

类成员函数指针区别于用法

通常的函数指针大家已经非常熟悉了.但我们今天讨论一下类成员函数指针的用法. 今天我们来看一下成员函数指针,加入我们想要声明一个 void CTest::Show()成员函数指针类型,那么我们一般的做法是: typedef void(CTest::*pShow)(); 从上面可以看出一些和一般函数指针类型不同的地方.让我们把他和一般的函数声明比较一下.下面是一般的函数声明: typedef void(*pShow)(); 我们可以看出成员函数指针和一般函数指针的不同,那就是成员函数指针声明时加上类