8961|11

80

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

CE6下 用CreateDIBSection即使用了DeleteObject释放 为什么还会造成CE内存泄露?wince系统自身的问题? [复制链接]

if (hBitmap)
{
  DeleteObject(hBitmap) ;
  hBitmap=NULL;
}

MemDC=::CreateCompatibleDC(dc);
hBitmap=::CreateDIBSection(dc,m_lpBMI,DIB_RGB_COLORS,(VOID**)&m_pBits,NULL,0);
if(hBitmap!=0)
{
  SelectObject(MemDC,hBitmap);
}

当DIB的m_lpBMI里面的位图信息大概1M时候 连续调用上面这段代码多次 就会产生内存不足了 检查了代码 每次用CreateDIBSection产生空间前 已经用DeleteObject(hBitmap) 释放了,这个难道是系统本身的内存泄露吗?

此帖出自WindowsCE论坛

最新回复

受教了,多谢指点  详情 回复 发表于 2008-10-10 08:05
点赞 关注
 

回复
举报

64

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
你还需要

DeleteDC(MemDC);
此帖出自WindowsCE论坛
 
 
 

回复

90

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
恕我直言,这段代码漏洞百出,不仅仅是一个问题。
此帖出自WindowsCE论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

4
 
代码是部分的,我的意思是这样的 不是全部的 我现在想表达的是 在CE下 用CreateDIBSection开辟空间 然后用DeleteObject 删除句柄 而我通过多次这样的操作会出现内存溢出 我就想问下 CE 是不是有这个问题 对于这个函数的问题 当然 同样的情况在WINDOWS XP 下没有问题
此帖出自WindowsCE论坛
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

5
 
代码问题。

要想说是系统问题,你就要把代码都贴出来,
否则就是代码问题。
此帖出自WindowsCE论坛
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

6
 
CreateDIBSection 是系统API,怎么会有错,你想哪里去了。你这段代码即使在XP下,也是有错误的代码,看得出来,写代码的人对GDI不了解,难免犯其他严重错误。
此帖出自WindowsCE论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

7
 
DWORD CDib::CreateDib1bits(int aWidth,int aHeight,HDC dc)//创建一个DIB文件
{       
        DWORD Size;
       
        Free();
        m_BMFH.bfReserved1=0;
        m_BMFH.bfReserved2=0;
        m_BMFH.bfOffBits=sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) *2;
        m_BMFH.bfSize=sizeof(BITMAPFILEHEADER);//整个文件大小 后面会赋值
        m_BMFH.bfType=DIB_HEADER_MARKER;

        // 分配DIB信息头和调色板的内存
        m_lpBMI = (LPBITMAPINFO)GlobalAllocPtr(GHND, m_BMFH.bfOffBits-sizeof(BITMAPFILEHEADER));
        if (m_lpBMI == 0)
                return 0;

        // 设置信息头中的信息
        m_lpBMI->bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
        m_lpBMI->bmiHeader.biWidth        = aWidth;
        m_lpBMI->bmiHeader.biHeight        = aHeight;
        m_lpBMI->bmiHeader.biPlanes        = 1;
        m_lpBMI->bmiHeader.biBitCount        =1;
        m_lpBMI->bmiHeader.biCompression =BI_RGB;
        m_lpBMI->bmiHeader.biSizeImage        = BytesPerLine()*aHeight;
        m_lpBMI->bmiHeader.biXPelsPerMeter = 0;
        m_lpBMI->bmiHeader.biYPelsPerMeter = 0;
        m_lpBMI->bmiHeader.biClrUsed        =2;
        m_lpBMI->bmiHeader.biClrImportant=0;
       
        m_lpBMI->bmiColors[0].rgbRed=255;
        m_lpBMI->bmiColors[0].rgbGreen=255;
        m_lpBMI->bmiColors[0].rgbBlue=255;
        m_lpBMI->bmiColors[0].rgbReserved= 0;

        m_lpBMI->bmiColors[1].rgbRed=0;
        m_lpBMI->bmiColors[1].rgbGreen=0;
        m_lpBMI->bmiColors[1].rgbBlue=0;
        m_lpBMI->bmiColors[1].rgbReserved= 0;


        // 计算图象数据内存的大小
        DWORD BitsSize=ComputeMetrics();
        CreatePalette();
        Size=sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) *2+BitsSize;
        m_BMFH.bfSize=Size;
        MemDC=::CreateCompatibleDC(dc);
        hBitmap=::CreateDIBSection(dc,m_lpBMI,DIB_RGB_COLORS,(VOID**)&m_pBits,NULL,0);
        if(hBitmap!=0)
        {
        ::SelectObject(MemDC,hBitmap);
        }
        else
                return 0;
        return Size;
}

void CDib::Free()
{
        // Make sure all member data that might have been allocated is freed.
        if (hBitmap)
        {
                DeleteObject(hBitmap) ;
                hBitmap=NULL;
        }
       
        if (MemDC)
        {
                DeleteDC(MemDC) ;
                MemDC=NULL;
        }
        if (m_pBits)
        {
                GlobalFreePtr(m_pBits);
                m_pBits = NULL;
        }
        if (m_lpBMI)
        {
                GlobalFreePtr(m_lpBMI);
                m_lpBMI = NULL;
        }
        if (m_pPalette)
        {
                m_pPalette->DeleteObject();
                delete m_pPalette;
                m_pPalette = NULL;
        }
       
}
这个是创建一个位图的原本代码 然后呢 我不断重复调用这个代码 就会产生内存泄漏
此帖出自WindowsCE论坛
 
 
 

回复

95

帖子

0

TA的资源

一粒金砂(初级)

8
 
我觉得API是没有问题 我认为是CE系统本身自己的问题,我问过些人 他们也表示CE系统是会存在内存泄漏问题的
此帖出自WindowsCE论坛
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

9
 
void CEditCardDlg::OnBnClickedButtonOpenfile()
{
if(m_DIB)
{
    delete m_DIB;
    m_DIB=NULL;
}
m_DIB=new CDib;
if(m_DIB->CreateDib1bits(pCard->Width,pCard->Height)!=0)        //创建新的空DIB
{
}
}
这个段就放在OPEN函数里面 每次就打开一个文件 当打开多次后 m_DIB->CreateDib1bits()返回的就是0了 跟踪后发现CreateDIBSection返回的是0这个说明内存没有开辟出来 而这里我始终是在新开前 把内存给Delete的
此帖出自WindowsCE论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

10
 
API就是系统,系统就是API,两者是一体的。Microsoft的人也从没和我说过这个API有内存泄漏,而且我用了很久也没发现过任何内存泄漏。我觉得你应该认真找找代码的问题,而不是怀疑系统问题。
我只能说你对GDI不了解,所以才会有这些问题,以前我研究GDI的时候,也总是被内存问题困扰,但是我后来彻底研究了WINCEGDI及内存体系之后,就极少遇到这些问题了。

可以指出你代码的几个明显问题

1.SelectObject(MemDC,hBitmap) 这句话错了
  因为当MemDC创建时,默认有占用一个像素的位图句柄在里面,所以应该保存起来。
  hOldBmp = SelectObject(MemDC,hBitmap);

2.这段代码错了
if (hBitmap)
{
  DeleteObject(hBitmap) ;
  hBitmap=NULL;
}

if (MemDC)
{
  DeleteDC(MemDC) ;
  MemDC=NULL;
}

因为你并没有将hBitmap 选出MemDC,就将它删除,极有可能删除失败。正确的做法应该是先将一个像素的位图还给MemDC,然后,才能删除你的hBitmap。
SelectObject(MemDC, hOldBmp) 因为根据GDI的原理,一个内存DC只能容纳一个HBITMAP对象。

3.这句话有问题
if (m_pBits)
{
GlobalFreePtr(m_pBits);
m_pBits = NULL;
}

因为m_pBits你并没有为它分配空间,却对它做释放,m_pBits仅仅是指向RGB原始数据的一个指针,它指向的位置应该是在GDI对象hBitmap所指位置的中间,这里对它释放可能会产生异常,因为它可能属于一个保护空间,内存页面是被锁定的,导致后面的释放代码失效。关于这点我查了一下我以前写的代码,是不需要对它做释放的。

4.你使用了不适合的内存API在WinCE上操作,关于内存API,你可以去查WINCE的帮助而不是XP的帮助,CE上一般使用LocalAlloc在本地堆上操作,在分离堆上一般使用HeapCreate,在大内存区域一般使用File map对象。

5.CE的内存体系有其特殊性,有些问题可能是你不懂得利用造成的,比如内存释放和分配的时机等等。

由于你使用的是类,我暂时只看到这些问题,也许其他地方也有问题,导致内存泄漏的原因是很多的。



此帖出自WindowsCE论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

11
 
多怀疑自己

不要总是怀疑别人有错
此帖出自WindowsCE论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

12
 
受教了,多谢指点
此帖出自WindowsCE论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表