帮忙 “Run-Time Check Failure #2 - Stack around the variable 'bmpinfo' was corrupted.”

dremi 2009-05-06 12:48:36
程序运行时出现这样的错误
“Run-Time Check Failure #2 - Stack around the variable 'bmpinfo' was corrupted.”
在网上查找了相关信息,大概是说stack溢出或什么对齐之类的

也有的说是把“c/c++代码生成这项”的"两者(/RTC1,等同于 /RTCsu)"改为默认值,这样改了,错误是消失了,但程序运行就得不到我想要的结果

BOOL CLSDC::RemoteDisplay(HBITMAP hbitmap, RECT size)
{
BITMAP bmp;
GetObject(hbitmap, sizeof(BITMAP), &bmp);

const int dataSize = (bmp.bmWidthBytes * bmp.bmHeight );

m_pMsgData = MapViewOfFile(m_hMsgFile, FILE_MAP_READ | FILE_MAP_WRITE,
0, 0, 0);

if (m_pMsgData == NULL)
return FALSE;

HDC hdc = GetDC(NULL);
HBITMAP bitmap = CreateCompatibleBitmap(hdc, bmp.bmWidth, bmp.bmHeight);

BITMAPINFO bmpinfo;
bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.bmiHeader.biBitCount = 0;

int res;
res = ::GetDIBits(hdc, bitmap, 0, 1, NULL, &bmpinfo, DIB_RGB_COLORS);
if(res == 0)
return FALSE;


SelectObject(hdc, hbitmap);

GetDIBits(hdc, hbitmap, 0, bmp.bmHeight, m_pMsgData, &bmpinfo, DIB_RGB_COLORS);

UnmapViewOfFile(m_pMsgData);


return TRUE;
}
...全文
3390 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
leeihcy 2010-08-23
  • 打赏
  • 举报
回复
我也碰到了这个问题。
看内存可以知道,在第二次调用GetDIBits的时候:

GetDIBits(hdc, hbitmap, 0, bmp.bmHeight, m_pMsgData, &bmpinfo, DIB_RGB_COLORS);

bmpinfo又被修改了,修改的范围超过了 sizeof(BITMAPINFOHEADER), 推测可能就是修改RGBQUAD了。但是对于 24位(或32位)的BMP图,应该是没有RGBQUAD内容的,BITMAPINFOHEADER后面直接就是数据了。

目前我是用:

int biSize = sizeof(BITMAPINFOHEADER)+ 256*sizeof(RGBQUAD);
BITMAPINFO* pbi =(BITMAPINFO*) new BYTE[biSize];

来实现了,但还是想知道具体bmpinfo被修改的原因。
leeihcy 2010-08-23
  • 打赏
  • 举报
回复
为什么不用GetBitmapBits?
Note This function is provided only for compatibility with 16-bit versions of Windows. Applications should use the GetDIBits function.

结果你传个0进去算怎么回事?
bmpinfo.bmiHeader.biBitCount = 0;

int res;
res = ::GetDIBits(hdc, bitmap, 0, 1, NULL, &bmpinfo, DIB_RGB_COLORS);
if(res == 0)
return FALSE;

在调用GetDIBits时,若指定LPVOID lpvBits 为NULL,

If lpvBits is NULL and the bit count member of BITMAPINFO is initialized to zero, GetDIBits fills in a BITMAPINFOHEADER structure or BITMAPCOREHEADER without the color table. This technique can be used to query bitmap attributes.

不知道您的MSDN看仔细了没
xxd_qd 2010-08-23
  • 打赏
  • 举报
回复
用biBitCount=0来调用GetDIBits?GetDIBits中的那个BITMAPINFO参数主要是个输入参数,是用来指定你想要的DIB的格式,而其中最重要的,就是要知道你想要获取的DIB的位数是多少,然后系统可以根据你要的位数进行转换,结果你传个0进去算怎么回事?让系统自己看着办?至少MSDN从来没说过“用biBitCount=0来调用GetDIBits,就会使用DDB本身的位数”。就算如此,那么你何必要用GetDIBits?为什么不用GetBitmapBits?
Ryanwen 2009-05-06
  • 打赏
  • 举报
回复
应该是结构体在内存字节对齐的原因 填充BITMAPINFO结构体的时候可能存在越界 我猜可能是这个 没有测试不好说
dremi 2009-05-06
  • 打赏
  • 举报
回复
我刚在再试了试,把bmpinfo改成类成员变量,而不是在这个函数的局部变量
int res;
res = ::GetDIBits(hdc, bitmap, 0, 1, NULL, &bmpinfo, DIB_RGB_COLORS);
if(res == 0)
return FALSE;
这些语句任然加上,错误也不会出现。
dremi 2009-05-06
  • 打赏
  • 举报
回复
去掉了,再用手动赋值这bmpinfo信息,错误没有,这原因是什么?
[Quote=引用 5 楼 Ryanwen 的回复:]
把下面这几句注释掉试试
int res;
res = ::GetDIBits(hdc, bitmap, 0, 1, NULL, &bmpinfo, DIB_RGB_COLORS);
if(res == 0)
return FALSE;
[/Quote]
Ryanwen 2009-05-06
  • 打赏
  • 举报
回复
我改动了这几个地方后测试没有问题

BITMAPINFO bmpinfo;
bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.bmiHeader.biBitCount = 0;

改为如下:


BITMAPINFO bmpinfo;
ZeroMemory(&bmpinfo, sizeof(BITMAPINFO));
bmpinfo.bmiHeader.biSize = 40;
bmpinfo.bmiHeader.biWidth = bmp.bmWidth;
bmpinfo.bmiHeader.biHeight = bmp.bmHeight;
bmpinfo.bmiHeader.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;

//int res;
//res = ::GetDIBits(hdc, bitmap, 0, 1, NULL, &bmpinfo, DIB_RGB_COLORS);
//if(res == 0)
// return FALSE;

Ryanwen 2009-05-06
  • 打赏
  • 举报
回复
把下面这几句注释掉试试
int res;
res = ::GetDIBits(hdc, bitmap, 0, 1, NULL, &bmpinfo, DIB_RGB_COLORS);
if(res == 0)
return FALSE;
dremi 2009-05-06
  • 打赏
  • 举报
回复
这个函数是在DLL库里面,这个DLL库的函数目前只写了两个,没有涉及动态内存的申请,只有一个内存映射文件的创建
m_hMsgFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024*1024, mappingFileName);

然后把图像信息写入内存映射文件中,方便其他进程共享
源程序中没有涉及动态内存分配。

所以这让我感到很困惑,不是知道是什么原因

wutaihua 2009-05-06
  • 打赏
  • 举报
回复
特别说明一下,不一定在函数这个地方返回时弹出了错误,就是这个地方的原因,错误报的是堆栈遭到了破坏,所以你要查看你所有动态申请内存的地方是否存在堆栈溢出的情况。函数返回的时候,需要检查内存中的堆栈,所以出了错误,并不代表这个函数引发的错误。还有内存空间的回收看是不是有操作不当的情况。我以前也遭遇过,所以楼主需要查找的范围不仅限于此
dremi 2009-05-06
  • 打赏
  • 举报
回复
改了结果还是一样

单步调试时,执行res = ::GetDIBits(hdc, bitmap, 0, 1, NULL, &bmpinfo, DIB_RGB_COLORS);
得到的结果是正确的

只是RemoteDisplay函数在返回时弹出那个错误
Ryanwen 2009-05-06
  • 打赏
  • 举报
回复
改成这样试试
ZeroMemory(&bmpinfo, sizeof(BITMAPINFO));
bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.bmiHeader.biBitCount = 0;
1、课程简介          ElasticStack 是一系列开源产品的合集,包括 Elasticsearch、Kibana、Logstash 以及 Beats 等,能够安全可靠地获取任何来源、任何格式的数据,并且能够实时地对数据进行搜索、分析和可视化。其中,Logstash和Beats负责数据的收集,Kibana负责结果数据的可视化展现,Elasticsearch作为核心部分用于数据的分布式存储以及索引。   我们可以使用ElasticStack进行收集并处理任何数据,最为经典的是用于实时日志数据的收集、存储、展现。在此之前,如果实现实时日志的分析,需要经过繁琐的架构设计并且使用多个系统实现,现在只需要使用ElasticStack即可实现功能强大的实时日志分析系统,ElasticStack不仅仅用来做日志分析,它可以处理任何的数据并且进行存储、展现。          在本套课程中,我们将全面的讲解ElasticStack技术栈,从环境的部署到技术的应用,再到项目实战,让我们不仅是学习框架技术的使用,而且可以学习到使用ElasticStack如何解决实际的问题,我们通过收集系统日志数据、服务器指标数据、nginx的运行数据等,多维度的展示了ElasticStack的应用范围,最终将分析的结果数据非常友好的展现出来,没错!不需要前端的参与也可以做出“高大上”的结果显示页。   2、适应人群   有一定的Java基础,并且要有一定的web开发基础。   3、课程亮点          系统的学习ElasticStack技术栈,掌握最先进的搜索、数据收集等技术。   l  Elasticsearch   n  快速入门   n  核心详解   n  中文分词   n  Elasticsearch集群   n  Java客户端的应用   l  Beats & Kibana & Logstash   n  Filebeat(文件采集器)   n  Metricbeat(指标采集器)   n  采集Nginx的日志以及指标数据   n  Kibana自定义仪表盘   n  Logstash自定义数据处理   l  综合练习   n  收集APP产生的日志进行实时展现   n  Filebeat采集日志   n  Logstash处理数据   n  Kibana 自定义仪表盘展现   4、主讲内容   章节一:Elasticsearch入门   1.     快速入门   2.     核心讲解   3.     中文分词   4.     全文搜索   5.     Elasticsearch集群   章节二:Beats   1.     Beats 简介   2.     Filebeat采集Nginx日志   3.     Metricbeat采集Nginx指标数据   章节三:Kibana   1.     Kibana简介   2.     Metricbeat 仪表盘   3.     Nginx 指标仪表盘   4.     Nginx 日志仪表盘   5.     自定义图表   章节四:Logstash   1.     Logstash简介   2.     配置详解   3.     读取自定义日志   章节五:综合练习   1.     流程说明   2.     Filebeat采集日志   3.     Logstash处理数据   4.     Kibana 自定义仪表盘展现

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧