windows GDI调色板是否存在内存泄露 之鉴 free函数用法

根据《Opengl超级宝典》第三版的范例程序,可知这么一段代码:

HPALETTE GetOpenGLPalette(HDC hDC)
{
 HPALETTE hRetPal = NULL;
 PIXELFORMATDESCRIPTOR pfd;
 LOGPALETTE *pPal;
 int nPixelFormat;
 int nColors;
 int i;
 BYTE RedRange,GreenRange,BlueRange;

 nPixelFormat = GetPixelFormat(hDC);
 DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR),&pfd);

 if(!(pfd.dwFlags & PFD_NEED_PALETTE))
  return NULL;

 nColors = 1 << pfd.cColorBits;

 pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE)+nColors*sizeof(PALETTEENTRY));

 pPal->palVersion = 0x300;
 pPal->palNumEntries = nColors;

 RedRange = (1<<pfd.cRedBits) - 1;
 GreenRange = (1<<pfd.cGreenBits) - 1;
 BlueRange = (1<<pfd.cBlueBits) - 1;

 for(i=0; i < nColors;i++)
 {
  pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
  pPal->palPalEntry[i].peRed = (unsigned char)(
   (double)pPal->palPalEntry[i].peRed * 255.0 / RedRange);

  pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
  pPal->palPalEntry[i].peGreen = (unsigned char)(
   (double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);

  pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
  pPal->palPalEntry[i].peBlue = (unsigned char)(
   (double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);

  pPal->palPalEntry[i].peFlags = (unsigned char)NULL;
 }

 hRetPal = CreatePalette(pPal);

 SelectPalette(hDC,hRetPal,FALSE);
 RealizePalette(hDC);

 free(pPal);

 return hRetPal;

其中,

pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE)+nColors*sizeof(PALETTEENTRY));

这里分配了nColors(假设为256色系统)个PALETTEENTRY结构大小的空间加上一个LOGPALETTE大小的空间,其结构如下:


typedef struct tagLOGPALETTE {
    WORD        palVersion;
    WORD        palNumEntries;
    PALETTEENTRY        palPalEntry[1];
} LOGPALETTE, *PLOGPALETTE, NEAR *NPLOGPALETTE, FAR *LPLOGPALETTE;


typedef struct tagPALETTEENTRY {
    BYTE        peRed;
    BYTE        peGreen;
    BYTE        peBlue;
    BYTE        peFlags;
} PALETTEENTRY, *PPALETTEENTRY, FAR *LPPALETTEENTRY;

可知LOGPALETTE结构中存在一个PALETTEENTRY大小的结构而非指针,那么就是说在释放了动态分配的pPal 以后是否还能够使palPalEntry[0]保存下来,我的答案是“不可能”(这里是我理解free只释了放单个LOGPALETTE结构大小空间的错误所致,请大家注意)。

所以这里将代码

 for(i=0; i < nColors;i++)

改为:

 for(i=1; i <= nColors;i++)

但是另外一个问题出现了,动态分配的空间是否被CreatePalette函数所控制,还是这个函数只是复制了调色板中的内容,我猜测如果不是复制(而是直接传递指针),肯定会出现内存泄露,所以答案应该是复制了这段调色板内存。

所以这个for循环不需要修改。还是

 for(i=0; i < nColors;i++)

然而在释放阶段,应该对所有已经分配的内存,即为pPal所分配的所有内存,而不止LOGPALETTE结构,所以,可以肯定的是在malloc时系统内部已经进行的已分配内存快的纪录,在free的时候就根据这些纪录来释放空间。

MSDN上有这么一段话:

The number of freed bytes is equivalent to the number of bytes requested when the block was allocated (or reallocated, in the case of realloc).

就是这么解释的。

所以创建调色板是对内容进行复制。

以上内容属于个人愚见,还请大家多多指点改正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值