- 浏览: 508839 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
jkxydp:
算法运行的结果根本就不对。
BM算法. -
soarwindzhang:
感谢博主的分享,我今天看了您的UFSET非递归的路径压缩时感觉 ...
并查集 -
zhangning290:
楼主好像只考虑了坏字符规则,。没有考虑好后缀
BM算法. -
lsm0622:
文字描述有错误 误导新学者
求有向图的强连通分量(scc):Tarjan算法 -
knightchen:
博主,你太强了!这篇文章对我学习C++多线程很有帮助!谢谢
并发学习之一_windows下ZThread在CodeBlocks上的安装与配置
1,什么时候需要撰写一份自己的new或delete?
多半是为了提高效率,例如对于需要动态配置大量细小空间的程序.
如:
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
实例代码:
4,上面new一开始分配了大量的内存,但是delete始终没有释放这块内存.
实际上,这里没有memory leak的问题.
内存泄露的问题是"配置内存后,所有指向该内存的指针都遗失了",这样内存就没有办法归还给内存.
我们的方法每一个大内存被 打破为一个个小内存,然后放置于free list中,执行new从free list中拿走,调用delete时,又会被放回free list中.
可见这些内存总是可以访问到,因此没有内存泄露的问题.
我们可以称这块大的内存为memory pool.
memory leak可能无限扩大,而memory pool的成长绝不会大过申请的内存.
由于一些病理上的行为,我们无需释放这个大的memory pool.
例如:
多半是为了提高效率,例如对于需要动态配置大量细小空间的程序.
如:
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 ; }
发表评论
-
条款43:明智地使用多继承
2010-06-08 09:33 14111,多继承带来的一个根本性的复杂性:模棱两可. 例如: # ... -
条款44:说出你的意思并了解你所说的每一句话
2010-06-08 09:30 8101,彻底了解不同的面向对象架构在C++中的意义. 2,声明一 ... -
条款30:避免写出member function,传回一个non-const function或reference并指向private或protect成员
2010-06-08 09:29 12281,先看一个例子: class Address { ... } ... -
条款4:尽量使用C++风格的注释形式
2010-06-07 09:49 7551,抛弃"/*...*/",改用" ... -
条款39:避免在继承体系中做向下转型(downcast)动作
2010-06-01 10:37 14871,先看个例子: class Person { ... }; ... -
条款2:尽量以<iostream>取代<stdio.h>
2010-06-01 10:36 10101,scanf和printf的缺点:不具有型别安全(type- ... -
条款1:尽量以const和inline取代#define
2010-06-01 10:35 9561,意思就是"尽量以编译器(compiler)&qu ... -
条款42:明智地使用private inheritance(私有继承)
2010-05-29 17:51 10051,先搞清楚private inheritance的行为: ( ... -
条款41:区分inheritance和template
2010-05-29 17:50 7041,首先考虑一个问题: 型别T会影响class的行为吗? 如果 ... -
条款40:通过layering技术来模塑"有一个"(has-a)或"根据某物实现(is-implemented-in-terms-of)"
2010-05-29 17:48 7991,所谓laying,就是以一个class为本,建立另外一个c ... -
条款38:绝对不要重新定义继承而来的缺省参数值
2010-05-29 17:48 8121,首先可以安全的把问题讨论局限于"继承一个带有缺省 ... -
条款37:绝对不要重新定义继承而来的非虚拟函数
2010-05-29 17:47 7641,先看个例子: class B { public: vo ... -
条款36:区分接口继承和实现继承
2010-05-29 17:46 8801,public继承分为两类:接口继承和实现继承. 这两种继承 ... -
条款35:确定你的public继承,模塑出"isa"的关系
2010-05-29 17:46 9971,C++面向对象程序设计最重要的原则: public继承意味 ... -
条款29:避免传回内部数据的handles
2010-05-28 10:35 13901,考虑下面的代码: class string { oper ... -
条款28:尝试切割global namesapce
2010-05-28 10:34 7101,namesapce的使用 namespace std{ ... -
条款50:加强自己对C++的了解
2010-05-25 11:46 8931,只推荐两本书: (1)D&E: The Desig ... -
条款49:尽量让自己熟悉C++标准库
2010-05-25 11:46 8061,标准库的每一样东西几乎都在namespace std中,然 ... -
条款48:不要对编译器的警告视而不见
2010-05-25 11:45 7931,在你忽略一个警告之前,你必须精确了解编译器企图告诉你的是什 ... -
条款47:使用non-local static objects之前先确定它已有初值
2010-05-25 11:45 8581,当一个编译单元内某对象的初始化动作,与另一个编译单元内某对 ...
相关推荐
这是一个正在进行的项目。 该项目的目的是简化环境中的部署和操作。 它于2016年在Amadeus内部开始,我们最初将该项目设计为在上运行。 这是我们的Redis-Operator的第二个版本,该版本现在基于Kubernetes ...
使用部署要创建运算符,可以直接使用kubectl创建它: kubectl create -f https://raw.githubusercontent.com/spotahome/redis-operator/master/example/operator/all-redis-operator-resources.yaml这将创建一个名为...
编写一个程序,接收一个2×3的二维数组,找出并输出数组中的最大值及其位置,然后输出整个数组。 #### 代码分析 ```c #include main() {int col,row,i,j; inta[2][3]; printf("Enterarray(2*3):"); for(i=0;i;i++) ...
(10)在关系模式中inotice中inoticeID为主键,所以在所包含属性inoticeID的函数依赖是一个superkey。所以一定属于BCNF。 二、数据库的概念结构设计 病人资料管理系统的E-R模型 三、数据库的物理结构设计 ...
简介OperatorFabric是一个模块化,可扩展的工业强度平台,可用于电力,水和其他公用事业运营。 它旨在通过两种方式促进公用事业的运营活动: 将实时业务事件集中在一个地方,以避免使用多个屏幕/软件。 为此,...