[100分][新手有关问题] 帮小弟我看看这段代码哪里发生了内存泄漏,刚学不懂

[100分][新手问题] 帮我看看这段代码哪里发生了内存泄漏,刚学不懂。HRGNBitmapToRegion(HBITMAPhBmp,COLORR

[100分][新手问题] 帮我看看这段代码哪里发生了内存泄漏,刚学不懂。
HRGN   BitmapToRegion(HBITMAP   hBmp,   COLORREF   crTransparentColor,   COLORREF   crTolerance,   const   LPRECT   prcSrounce)
{
HRGN   hRgn   =   NULL;

if   (hBmp)
{
//   Create   a   memory   DC   inside   which   we   will   scan   the   bitmap   content
HDC   hMemDC   =   CreateCompatibleDC(NULL);
if   (hMemDC)
{
//   Get   bitmap   size
BITMAP   bm;
GetObject(hBmp,   sizeof(bm),   &bm);

//   Create   a   32   bits   depth   bitmap   and   select   it   into   the   memory   DC
BITMAPINFOHEADER   RGB32BITSBITMAPINFO   =   {
sizeof(BITMAPINFOHEADER),         //   biSize
bm.bmWidth,                                         //   biWidth;
bm.bmHeight,                                 //   biHeight;
1,                                                         //   biPlanes;
32,                                                         //   biBitCount
BI_RGB,                                                 //   biCompression;
0,                                                         //   biSizeImage;
0,                                                         //   biXPelsPerMeter;
0,                                                         //   biYPelsPerMeter;
0,                                                         //   biClrUsed;
0                                                         //   biClrImportant;
};
VOID   *   pbits32;
HBITMAP   hbm32   =   CreateDIBSection(hMemDC,   (BITMAPINFO   *)&RGB32BITSBITMAPINFO,   DIB_RGB_COLORS,   &pbits32,   NULL,   0);
if   (hbm32)
{
HBITMAP   holdBmp   =   (HBITMAP)SelectObject(hMemDC,   hbm32);

//   Create   a   DC   just   to   copy   the   bitmap   into   the   memory   DC
HDC   hDC   =   CreateCompatibleDC(hMemDC);
if   (hDC)


{
//   Get   how   many   bytes   per   row   we   have   for   the   bitmap   bits   (rounded   up   to   32   bits)
BITMAP   bm32;
GetObject(hbm32,   sizeof(bm32),   &bm32);
while   (bm32.bmWidthBytes   %   4)
bm32.bmWidthBytes++;

//   Copy   the   bitmap   into   the   memory   DC
HBITMAP   holdBmp   =   (HBITMAP)SelectObject(hDC,   hBmp);

RECT   rcSource;   //  
if(prcSrounce)    
{
rcSource   =   *prcSrounce;
//  
bm.bmWidth   =   prcSrounce-> right   -   prcSrounce-> left;
bm.bmHeight   =   prcSrounce-> bottom   -   prcSrounce-> top;
}
else
SetRect(&rcSource,   0,   0,   bm.bmWidth,   bm.bmHeight);

BitBlt(hMemDC,   0,   0,   rcSource.right-rcSource.left,   rcSource.bottom-rcSource.top,   hDC,   rcSource.left,   rcSource.top,   SRCCOPY);
#if   0
HDC   hdc   =   ::GetDC(0);
BitBlt(hdc,   0,   0,   rcSource.right-rcSource.left,   rcSource.bottom-rcSource.top,   hMemDC,   0,   0,   SRCCOPY);
ReleaseDC(0,   hdc);
#endif

//   For   better   performances,   we   will   use   the   ExtCreateRegion()   function   to   create   the
//   region.   This   function   take   a   RGNDATA   structure   on   entry.   We   will   add   rectangles   by
//   amount   of   ALLOC_UNIT   number   in   this   structure.
#define   ALLOC_UNIT         100
DWORD   maxRects   =   ALLOC_UNIT;
HANDLE   hData   =   GlobalAlloc(GMEM_MOVEABLE,   sizeof(RGNDATAHEADER)   +   (sizeof(RECT)   *   maxRects));   //////   BoundsChecker报这行有内存泄漏
RGNDATA   *pData   =   (RGNDATA   *)GlobalLock(hData);
pData-> rdh.dwSize   =   sizeof(RGNDATAHEADER);
pData-> rdh.iType   =   RDH_RECTANGLES;
pData-> rdh.nCount   =   pData-> rdh.nRgnSize   =   0;
SetRect(&pData-> rdh.rcBound,   MAXLONG,   MAXLONG,   0,   0);

//   Keep   on   hand   highest   and   lowest   values   for   the   "transparent "   pixels
BYTE   lr   =   GetRValue(crTransparentColor);
BYTE   lg   =   GetGValue(crTransparentColor);
BYTE   lb   =   GetBValue(crTransparentColor);
BYTE   hr   =   min(0xff,   lr   +   GetRValue(crTolerance));
BYTE   hg   =   min(0xff,   lg   +   GetGValue(crTolerance));
BYTE   hb   =   min(0xff,   lb   +   GetBValue(crTolerance));

//   Scan   each   bitmap   row   from   bottom   to   top   (the   bitmap   is   inverted   vertically)
BYTE   *p32   =   (BYTE   *)bm32.bmBits   +   (bm32.bmHeight   -   1)   *   bm32.bmWidthBytes;
for   (int   y   =   0;   y   <   bm.bmHeight;   y++)
{
//   Scan   each   bitmap   pixel   from   left   to   right


for   (int   x   =   0;   x   <   bm.bmWidth;   x++)
{
//   Search   for   a   continuous   range   of   "non   transparent   pixels "
int   x0   =   x;
LONG   *p   =   (LONG   *)p32   +   x;
while   (x   <   bm.bmWidth)
{
BYTE   b   =   GetRValue(*p);
if   (b   > =   lr   &&   b   <=   hr)
{
b   =   GetGValue(*p);
if   (b   > =   lg   &&   b   <=   hg)
{
b   =   GetBValue(*p);
if   (b   > =   lb   &&   b   <=   hb)
//   This   pixel   is   "transparent "
break;
}
}
p++;
x++;
}

if   (x   >   x0)
{
//   Add   the   pixels   (x0,   y)   to   (x,   y+1)   as   a   new   rectangle   in   the   region
if   (pData-> rdh.nCount   > =   maxRects)
{
GlobalUnlock(hData);
maxRects   +=   ALLOC_UNIT;
hData   =   GlobalReAlloc(hData,   sizeof(RGNDATAHEADER)   +   (sizeof(RECT)   *   maxRects),   GMEM_MOVEABLE);  
pData   =   (RGNDATA   *)GlobalLock(hData);
}
RECT   *pr   =   (RECT   *)&pData-> Buffer;
SetRect(&pr[pData-> rdh.nCount],   x0,   y,   x,   y+1);
if   (x0   <   pData-> rdh.rcBound.left)
pData-> rdh.rcBound.left   =   x0;
if   (y   <   pData-> rdh.rcBound.top)
pData-> rdh.rcBound.top   =   y;
if   (x   >   pData-> rdh.rcBound.right)
pData-> rdh.rcBound.right   =   x;
if   (y+1   >   pData-> rdh.rcBound.bottom)
pData-> rdh.rcBound.bottom   =   y+1;
pData-> rdh.nCount++;

//   On   Windows98,   ExtCreateRegion()   may   fail   if   the   number   of   rectangles   is   too
//   large   (ie:   >   4000).   Therefore,   we   have   to   create   the   region   by   multiple   steps.
if   (pData-> rdh.nCount   ==   2000)
{
HRGN   h   =   ExtCreateRegion(NULL,   sizeof(RGNDATAHEADER)   +   (sizeof(RECT)   *   maxRects),   pData);
if   (hRgn)
{
CombineRgn(hRgn,   hRgn,   h,   RGN_OR);
DeleteObject(h);
}
else
hRgn   =   h;
pData-> rdh.nCount   =   0;
SetRect(&pData-> rdh.rcBound,   MAXLONG,   MAXLONG,   0,   0);
}
}
}

//   Go   to   next   row   (remember,   the   bitmap   is   inverted   vertically)
p32   -=   bm32.bmWidthBytes;
}

//   Create   or   extend   the   region   with   the   remaining   rectangles


HRGN   h   =   ExtCreateRegion(NULL,   sizeof(RGNDATAHEADER)   +   (sizeof(RECT)   *   maxRects),   pData);
if   (hRgn)
{
CombineRgn(hRgn,   hRgn,   h,   RGN_OR);
DeleteObject(h);
}
else
hRgn   =   h;

//   Clean   up
                                        ::SelectObject(hDC,   holdBmp);
                                        ::DeleteDC(hDC);
}

DeleteObject(SelectObject(hMemDC,   holdBmp));
}

DeleteDC(hMemDC);
}
}

return   hRgn;
}

-------------------------------------------------------
我用BoundsChecker检测,报HANDLE   hData   =   GlobalAlloc(GMEM_MOVEABLE,   sizeof(RGNDATAHEADER)   +   (sizeof(RECT)   *   maxRects));这句有内存泄漏。

帮忙看看!怎么解决。



[解决办法]
你要用GlobalFree将内存释放才行
[解决办法]
GlobalAlloc有一种情况下要用就是CreateStreamOnHGlobal
GlobalAlloc在Win16中就已经有了,这个函数返回一个句柄,通过这个句柄,两个进程可以共享一块内存
GlobalAlloc/GlobalFree
[解决办法]
呵呵,要先unlock,才能free
所以
GlobalUnlock(hData);
GlobalFree(hData);
[解决办法]
VOID * pbits32;

[解决办法]

[解决办法]
bmBitmap是一个结构体,由于建立在栈上在函数执行完之后会自动释放
[解决办法]
没办法判断一个指针是否已经被释放了,所以要在释放指针后赋值为NULL,就是为了避免野指针,上面这种情况看来只能靠良好的编程习惯业解决了,在释放a时,也同时把b给赋值为NULL.
[解决办法]
mark
[解决办法]
好复杂啊
[解决办法]
这么麻烦