一不小心,漏了!

 这几天在写用遗传算法解决装箱问题的程序,碰到了好多奇怪的事情。其实奇怪的原因在于使用c++的指针不熟造成的,当然,指针不熟最常见的问题就是内存泄露了。想到一个很有意思的问题,即使不是我的程序的内存泄露,而我确实需要大量的内存该咋办?可以看一下这个帖子:

http://topic.csdn.net/u/20091027/16/8b8e3761-1569-4ffc-8528-bd560ada9265.html

好像也没有什么好办法。

发上面的帖子的时候,但是不是内存泄露,是我做内存测试而故意弄出来的。但是今天却发现了一个真正的泄露,程序一旦运行,就发现占用内存在一直的上升,然后到了2g的时候,就出现内存申请异常了,造成的原因,却有一定的启发性。

由于做的程序的计算量比较大,因此做程序的时候手头放了一本《提高C++性能的编程技术 》边看边参考,受益匪浅。其中有一条提到 缓式计算 ,大体意思是不要预先定义好对象,直到用得着的时候再定义,会提高性能,类似于下面的:


X x;

if (condition)

  x.DoSomthing;

这段代码,由于condition的存在,会导致x的构造有时候会成为一种浪费的开销,特别是当x的构造函数花费比较大的时候,因此写成下面的,效果会更好点:


if (condition){

  X x;

  x.DoSomthing;

}

问题就出在这里了。看我的代码

class CGenome { //染色体类 public: int ITEM_COUNTER; int MAX_ITEM; double dFitness;//适应值 int iBoxCount;//包含的箱子数量 CBox *boxs;//箱子数组,此染色体包含了多少个箱子 CGenome(void); CGenome(const CGenome &gen); CGenome &operator =(const CGenome &gen); void UpdateFitness();//计算适应度 void Mutation();//变异 public: ~CGenome(void); }; CGenome::CGenome(void) { randomSeq=NULL; items=NULL; boxs=NULL; } CGenome::~CGenome(void) { delete[]randomSeq; delete []items; delete []boxs; } CGenome::CGenome(const CGenome &gen) { //复制构造函数 } CGenome &CGenome::operator =(const CGenome &gen) { //赋值运算符重载 ITEM_COUNTER=gen.ITEM_COUNTER ; dFitness=gen.dFitness; iBoxCount=gen.iBoxCount ; boxs=new CBox[ITEM_COUNTER];//箱子数组,此染色体包含了多少个箱子 for(int i=0;i<ITEM_COUNTER;i++) { items[i]=gen.items[i]; boxs[i]=gen.boxs[i]; } return *this; } //下面是遗传算法类里面的调用 void CGA::CreateNextGen(int gen) { //生成下一代 //从选择出来的染色体中随机选择两个进行交叉 //形成新的子代,然后对子代进行变异 int i; int iIndex=-1; CGenome father,mother; i=0; while (i<POP_SIZE) { father=gens[SelectParent()]; mother=gens[SelectParent()]; CreateChild(father,mother, m_NextGens[i],m_NextGens[i+1]); i+=2; } }


定义了两个局部的CGenome father 和 mother,结果导致了内存的大量泄漏,原因在于由于使用了赋值运算符的重载,每次对father进行赋值的时候,都会申请一块内存,从而造成泄漏。

解决方法比较简单,只需在赋值运算重载中加一个判断,判断当前的boxs是否为NULL就可以了。

你可能感兴趣的:(编程,算法,测试,null,delete,Class)