`
kmplayer
  • 浏览: 498725 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

条款10:如果你写了一个opertor new,请对应写一个operator delete

 
阅读更多
1,什么时候需要撰写一份自己的new或delete?
多半是为了提高效率,例如对于需要动态配置大量细小空间的程序.
如:
class AirplaneRep{};
class Airplane
{
private:
    AirplaneRep* rep;
};


2,当我们用new配置一个Airplane对象时,实际获得的内存要比一个指针的空间多.
其原因是为了operator new和opertor delete的沟通.
缺省版的operator new可以配置任意大小的内存,同理,缺省版的operator delete应该能够释放由new配置的任意大小的内存.
因此必须通过某种办法让operator delete知道new配置了多少内存.
常用的方法:在new传回的前端"加挂"一些额外数据,说明配置的区块大小.
Airplane* pa=new Airplane;
实际获得的内存如下图所示:



3,我们可以利用每个Airplane对象的大小相同这个事实,为Airplane撰写一个定制的operator new,这样就不在需要对每个动态配置的对象分配记录区域.
常用的方法:
先用默认的new配置一大块内存,然后每一个Airplane所需的内存,便从这个大内存里挖取.
这里不要忘记还要给出定制的operator delete
实例代码:
#include <iostream>
using namespace std ;

class AirplaneRep{};
class Airplane
{
public:
    static void* operator new(size_t size);
    static void operator delete(void* collectObject,size_t size);
private:
    union
    {
        AirplaneRep* rep;
        Airplane* next;
    };
    static const int BLOCK_SIZE;
    static Airplane* headOfFreeList;
};

void* Airplane::operator new(size_t size)
{
    if(size!=sizeof(Airplane))
        return ::operator new(size);
    Airplane* p=headOfFreeList;
    //如果有效,还有内存可以分配
    if(p)
        headOfFreeList=p->next;
    else
    {
        Airplane* newBlock=static_cast<Airplane*>(::operator new(BLOCK_SIZE*sizeof(Airplane)));
        for(int i=0;i<BLOCK_SIZE-1;i++)
            newBlock[i].next=&newBlock[i+1];
        //NULL作为大内存的结束
        newBlock[BLOCK_SIZE-1].next=0;
        p=newBlock; //第一个传回
        headOfFreeList=&newBlock[1];
    }
    return p;
}

void Airplane::operator delete(void* collectObject,size_t size)
{
    if(size==0)
        return; //不执行任何操作
    if(size!=sizeof(Airplane))
    {
        ::operator delete(collectObject);
        return;
    }
    Airplane* collect=static_cast<Airplane*>(collectObject);
    //将回收的区间放在head的前端
    collect->next=headOfFreeList;
    headOfFreeList=collect;

}

Airplane* Airplane::headOfFreeList;//默认为0
const int Airplane::BLOCK_SIZE=512;

class Airplane2
{
private:
    union
    {
        AirplaneRep* rep;
        Airplane* next;
    };
    static const int BLOCK_SIZE;
    static Airplane* headOfFreeList;
};

int main ()
{
    const int cnt=128;
    //对象Airplane定制new
    Airplane* pa[cnt];
    for(int i=0;i<cnt;i++)
        pa[i]=new Airplane();
    cout<<(int)pa[127]-(int)pa[125]<<endl;
    for(int i=0;i<cnt;i++)
        delete pa[i];

    //对象Airplane2系统默认new
    Airplane2* pb[cnt];
    for(int i=0;i<cnt;i++)
        pb[i]=new Airplane2();
    cout<<(int)pb[127]-(int)pb[125]<<endl;
    for(int i=0;i<cnt;i++)
        delete pb[i];

	return 0 ;
}

4,上面new一开始分配了大量的内存,但是delete始终没有释放这块内存.
实际上,这里没有memory leak的问题.
内存泄露的问题是"配置内存后,所有指向该内存的指针都遗失了",这样内存就没有办法归还给内存.
我们的方法每一个大内存被 打破为一个个小内存,然后放置于free list中,执行new从free list中拿走,调用delete时,又会被放回free list中.
可见这些内存总是可以访问到,因此没有内存泄露的问题.
我们可以称这块大的内存为memory pool.
memory leak可能无限扩大,而memory pool的成长绝不会大过申请的内存.
由于一些病理上的行为,我们无需释放这个大的memory pool.
例如:
int main ()
{

    //获得大内存
    Airplane* pa=new Airplane();
    //释放大内存
    delete pa;

    //再次获得大内存
    pa=new Airplane();
    //再次释放
    delete pa;

	return 0 ;
}
  • 大小: 3.8 KB
分享到:
评论

相关推荐

    Redis-Operator:Redis Operator在Kubernetes上创建配置管理Redis集群

    这是一个正在进行的项目。 该项目的目的是简化环境中的部署和操作。 它于2016年在Amadeus内部开始,我们最初将该项目设计为在上运行。 这是我们的Redis-Operator的第二个版本,该版本现在基于Kubernetes ...

    redis-operator:Redis Operator通过Kubernetes上的哨兵自动故障转移创建配置管理高可用性Redis

    使用部署要创建运算符,可以直接使用kubectl创建它: kubectl create -f https://raw.githubusercontent.com/spotahome/redis-operator/master/example/operator/all-redis-operator-resources.yaml这将创建一个名为...

    病人资料管理系统

    (10)在关系模式中inotice中inoticeID为主键,所以在所包含属性inoticeID的函数依赖是一个superkey。所以一定属于BCNF。 二、数据库的概念结构设计 病人资料管理系统的E-R模型 三、数据库的物理结构设计 ...

    operatorfabric-core:主操作员面料程序

    简介OperatorFabric是一个模块化,可扩展的工业强度平台,可用于电力,水和其他公用事业运营。 它旨在通过两种方式促进公用事业的运营活动: 将实时业务事件集中在一个地方,以避免使用多个屏幕/软件。 为此,...

    【车牌识别】 GUI BP神经网络车牌识别(带语音播报)【含Matlab源码 668期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    【作业视频】六年级第1讲--计算专项训练(2022-10-28 22-51-53).mp4

    【作业视频】六年级第1讲--计算专项训练(2022-10-28 22-51-53).mp4

    3文件需求申请单.xls

    3文件需求申请单.xls

    【脑肿瘤检测】 GUI SOM脑肿瘤检测【含Matlab源码 2322期】.zip

    【脑肿瘤检测】 GUI SOM脑肿瘤检测【含Matlab源码 2322期】

    GOGO语言基础教程、实战案例和实战项目讲解

    GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解

    全国计算机等级考试二级笔试样卷C语言程序设计

    全国计算机等级考试二级笔试样卷C语言程序设计主要考察考生对C语言编程的基础知识、语法和编程能力的掌握程度。考试内容主要包括C语言程序的结构、数据类型及其运算等基础知识,以及循环、条件语句、函数等编程能力。

    Excel模板个人简历文艺清新单页01.docx

    Excel模板个人简历文艺清新单页01.docx

    【图像边缘检测】自适应阈值的八方向和四方向sobel图像边缘检测【含Matlab源码 2058期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    HC070-3.5标定版描述文件及标定版ps文件

    HC070-3.5标定版描述文件及标定版ps文件

    【目标跟踪】 GUI帧差法结合卡尔曼滤波行人姿态识别【含Matlab源码 1127期】.zip

    【目标跟踪】 GUI帧差法结合卡尔曼滤波行人姿态识别【含Matlab源码 1127期】

    ISO文件电子文档发文删文记录表.xls

    ISO文件电子文档发文删文记录表.xls

    【红绿灯识别】机器视觉红绿灯识别【含Matlab源码 4044期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    【图像去噪】稀疏表示KSVD彩色图像去噪(含PSNR)【含Matlab源码 4261期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    node-v0.10.48-sunos-x86.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v0.10.48-linux-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    PREEvision关于ECU软件与诊断设计的一致性功能

    PREEvision关于ECU软件与诊断设计的一致性功能

Global site tag (gtag.js) - Google Analytics