根据《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).
就是这么解释的。
所以创建调色板是对内容进行复制。
以上内容属于个人愚见,还请大家多多指点改正。