使用BITMAPINFO创建灰度桌面图像遇C6255警告求助
使用BITMAPINFO创建灰度位图时解决C6255警告的建议
我需要通过BITMAPINFO从桌面创建灰度图像,但编译时一直收到警告:
Warning C6255 _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
相关代码如下:
HBITMAP CreateGreyscaleBitmap(int cx, int cy) { BITMAPINFO* pbmi = (BITMAPINFO*)alloca(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256); pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = cx; pbmi->bmiHeader.biHeight = cy; pbmi->bmiHeader.biPlanes = 1; pbmi->bmiHeader.biBitCount = 8; pbmi->bmiHeader.biCompression = BI_RGB; pbmi->bmiHeader.biSizeImage = 0; pbmi->bmiHeader.biXPelsPerMeter = 14173; pbmi->bmiHeader.biYPelsPerMeter = 14173; pbmi->bmiHeader.biClrUsed = 0; pbmi->bmiHeader.biClrImportant = 0; for (int i = 0; i < 256; i++) { pbmi->bmiColors[i].rgbRed = i; pbmi->bmiColors[i].rgbGreen = i; pbmi->bmiColors[i].rgbBlue = i; pbmi->bmiColors[i].rgbReserved = 0; } PVOID pv; return CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pv, NULL, 0); }
警告原因与解决方法
原因
alloca直接在栈上分配内存,栈空间通常只有几MB,一旦分配的内存超出栈剩余空间就会触发栈溢出异常。虽然你这里分配的内存(1028字节)很小,但编译器依然会警告其潜在风险。
方案1:改用_malloca
_malloca是CRT提供的安全替代函数,会根据分配大小自动选择栈或堆分配,分配后必须用_freea释放内存:
HBITMAP CreateGreyscaleBitmap(int cx, int cy) { HBITMAP hBitmap = NULL; BITMAPINFO* pbmi = (BITMAPINFO*)_malloca(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256); if (pbmi) { pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = cx; pbmi->bmiHeader.biHeight = cy; pbmi->bmiHeader.biPlanes = 1; pbmi->bmiHeader.biBitCount = 8; pbmi->bmiHeader.biCompression = BI_RGB; pbmi->bmiHeader.biSizeImage = 0; pbmi->bmiHeader.biXPelsPerMeter = 14173; pbmi->bmiHeader.biYPelsPerMeter = 14173; pbmi->bmiHeader.biClrUsed = 0; pbmi->bmiHeader.biClrImportant = 0; for (int i = 0; i < 256; i++) { pbmi->bmiColors[i].rgbRed = i; pbmi->bmiColors[i].rgbGreen = i; pbmi->bmiColors[i].rgbBlue = i; pbmi->bmiColors[i].rgbReserved = 0; } PVOID pv; hBitmap = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pv, NULL, 0); _freea(pbmi); } return hBitmap; }
方案2:使用栈上固定大小结构体
因为你需要的BITMAPINFO大小是固定的(包含256个灰度色表),可以直接定义一个包含BITMAPINFOHEADER和256个RGBQUAD的局部结构体,完全避免动态分配:
typedef struct { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[256]; } GrayBitmapInfo; HBITMAP CreateGreyscaleBitmap(int cx, int cy) { GrayBitmapInfo bmi = {0}; bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = cx; bmi.bmiHeader.biHeight = cy; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 8; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = 0; bmi.bmiHeader.biXPelsPerMeter = 14173; bmi.bmiHeader.biYPelsPerMeter = 14173; bmi.bmiHeader.biClrUsed = 0; bmi.bmiHeader.biClrImportant = 0; for (int i = 0; i < 256; i++) { bmi.bmiColors[i].rgbRed = i; bmi.bmiColors[i].rgbGreen = i; bmi.bmiColors[i].rgbBlue = i; bmi.bmiColors[i].rgbReserved = 0; } PVOID pv; return CreateDIBSection(NULL, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, &pv, NULL, 0); }
这个方案更高效安全,没有动态分配的开销,也不会触发编译器警告。
内容的提问来源于stack exchange,提问作者rundom lol
相关产品推荐
相关产品推荐

