比如一个这样的程序:void Func(CDC* dc)    
{
    CPen penSolid(PS_SOLID,1,RGB(226,226,201));    //在这里定义一个CPen的局部对象    pOldPen = dc->SelectObject(&penSolid1);    ......画一些操作
}void main()
{
    CDC dc;
  while(1)        //循环执行,会不会造成内存泄露???
   {
     Func(&dc);
   }
}
//****************************
请论坛的朋友们,帮我看看这样会不会造成内存泄露?
我在网上看的,有人说在函数Func中需要对penSolid进行deleteObject操作?可是这个是局部对象,不是应该
可以在超出作用域,自己析构吗?
还要不要显示deleteObject操作?
我在我的一个大程序中,没有进行deleteObject操作,任务管理器中显示的内存在慢慢增加;
但是我自己写一断小代码,循环执行不deleteObject,一直没有出现内存增加的情况。为什么??崩溃了?
另外,有人说在函数中,要先把这个画笔选出去,然后才能进行局部对象的自动析构(这不也说明了,上述代码是存在内存泄露的吗?可是我写一段代码为什么内存一直保持一定的范围没有增长呢?)
忘各位大侠给分析分析,多谢啊

解决方案 »

  1.   

    VC6.0,会对MFC的部分API或函数不支持或溢出的现象
      

  2.   

    这个可以自己析构 不用delete也可以 你看看你的程序是不是其他的地方有内存泄露的地方
      

  3.   

    上msdn的好好看看cpen 的DeleteObject(),这个函数,上面说虽然对象删除了,但是还有gdi的一些资源必须用这个函数删除
      

  4.   

    pOldPen = dc->SelectObject(&penSolid1); 
    DeleteObject(pOldPen);pOldPen 这个指针是你抄回来的?
      

  5.   

    首先,这段代码不会造成内存增加,但是,会造成GDI资源不停的增加!如果是VC6环境下,肯定会造成GDI资源不停的增加,直至最后崩溃!如果是2008环境,如果执行完画图,直接做一步dc->SelectObject(pOldPen);释放DC关联的画笔,那么,画笔会自己删除;如果不执行这一步,画笔一直被设备所用,那么肯定释放不了!那么,一样会不停的增加,最后崩溃的!
    其次,这段代码可以这么做:
    void Func(CDC* dc)    

        CPen penSolid(PS_SOLID,1,RGB(226,226,201));    //在这里定义一个CPen的局部对象     pOldPen = dc->SelectObject(&penSolid1);     ......画一些操作 
    dc->SelectObject(pOldPen);
    penSolid.DeleteObject();} 
    这要就可以删除画笔了!
    最后,你有没有发现,“其次”里面效率很低下?那么,最后应该这要改:
    void Func(CDC* dc)    

            ......画一些操作 
    } void main() 

        CDC dc; 
    CPen penSolid(PS_SOLID,1,RGB(226,226,201));    //在这里定义一个CPen的局部对象     pOldPen = dc.SelectObject(&penSolid1);   while(1)        //循环执行,会不会造成内存泄露??? 
      { 
        Func(&dc); 
      } 
    dc.SelectObject(pOldPen);
    penSolid.DeleteObject();} 有些地方可能说的不好或者不对,欢迎大家拍砖!
      

  6.   

    回8楼fandh
    谢谢你仔细的作答
    恩,我看一些资料,想着也应该是要进行下面两步
    dc->SelectObject(pOldPen); 
    penSolid.DeleteObject();    //如果是局部变量,我想可以省略这个步骤,可以自动析构,主要是上面要选出但问题是,我没有写这两步,就按照我在顶楼写的那段代码,专门使劲地循环,去观察内存和资源有没有泄露?可是一直显示没有泄露啊?为什么 我实在是搞不懂了?可在我的项目中又因为这两步没写,发现有内存泄露的情况。真是晕了另外:
    dc->SelectObject(pOldPen); 
    penSolid.DeleteObject();
    我觉得第二步可以不要,如果是局部释放的话?大家认为呢? 
      

  7.   

    penSolid.DeleteObject(); 
    这一步,我记得在win98下是绝对要的!后面的,的确可以省掉,但是,我建议你写上!
      

  8.   


    When an application no longer requires a given pen, it should call the CGdiObject::DeleteObject member function or destroy the CPen object so the resource is no longer in use.
    ============
    创建CPen的时候,是先创建一个资源,然后用对象指向资源。
    DeleteObject 删除的不是那个局部对象,而是局部对象指向的CPen资源。
    你那样,局部对象是析构了,但没有释放资源。
      

  9.   

    另外,资源的增加,不是内存泄露!你可以通过任务管理器查看在循环时,GDI资源是否不停的增加!你所说的内存泄露,可能其它地方造成的,你可以试试不调用这些代码试试!
      

  10.   

    回fandh
    GDI我也一直在观察,比较稳定不存在泄露
    我就是奇怪了
    我开始在顶楼写的那段测试代码中,也没有dc->SelectObject(pOldPen); 
    更没有penSolid.DeleteObject();
    为什么又不存在内存泄露和GID资源泄露呢? vc6.0环境,windows2003操作系统环境下 
      

  11.   

    多谢aoyihuashao的回复
    按照你的意思,就必须显示的调用
    dc->SelectObject(pOldPen); 
    penSolid.DeleteObject();
    这两步了吧可是为什么我用顶楼的那段代码测试,一直监测不到资源泄露呢?vc6.0环境,windows2003操作系统环境下  
      

  12.   

    楼主单步调试,看看GDI资源的个数是否增加!