一、数据越界
vc++ 2008调试过程说:Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.下面为被调试程序(我的目的是输出10个数中最大的数)
#include "stdafx.h" #include"stdio.h" void main() { int a[10]; int i,j,t; for (i=1;i<=10;i++) scanf_s("%d",&a[i]); for (j=1;j<=11;j++) for(i=0;i<=9;i++) if(a[i]>a[i+1]) { t=a[i]; a[i]=a[i+1]; a[i+1]=t; } printf("%d",a[0]); }
数组越界了,将int a[10];改为int a[11].因为int a[10]是指a[0]-a[9]这几个元素,而你读入的却包含了a[10],因此造成了数组越界.
二、
之前在网上下了个MFC程序,编译成功,但是运行后出现"Run-Time Check Failure #2 - Stack around the variable 'cinfo' was corrupted.“的中断,虽然点继续好像并不影响结果,但是有这个问题还是要解决。
上网查了相关的内容,网上说的是一个数组,在使用的时候超过下标,越界后出现该中断。因为是堆栈出现问题,应该是在使用的时候操作不当。
在我调试的程序中用到的是结构体,结构体里有指针。在一个函数里定义了结构体变量,对结构体处理的函数都是封装成库了,也看不到具体的操作,在使用到结构体的函数结束时(执行return后)出现该中断,设断点跟踪...太复杂了看不懂哪里的问题,接着在网上找了一堆相关的中断,有的说是内存分配不够,vs上的/RTC检查了此操作所以报错出来。
再找了一些网站。有的说msvc在debug下为栈上自动变量周围分配了一些保护空间。如果发生栈溢出, 就会写到保护空间上去。这样, 栈溢出就能被检查出来。然后我换成Release编译(太天真了),提示说是以前版本的,无法生成*&%……%#@!*
继续找...有的说把“c/c++代码生成这项”的"两者(/RTC1,等同于 /RTCsu)"改为“默认值”错误会消失,在项目属性那里,我改了...完全没有变化。
再继续找...说是发现有这样的说法“不一定在函数这个地方返回时弹出了错误,就是这个地方的原因,错误报的是堆栈遭到了破坏,所以你要查看你所有动态申请内存的地方是否存在堆栈溢出的情况。函数返回的时候,需要检查内存中的堆栈,所以出了错误,并不代表这个函数引发的错误。还有内存空间的回收看是不是有操作不当的情况。”。但是我的结构体操作函数都封装在库里面,看不到怎么办呢?继续看下去,发现有说到“我刚在再试了试,把bmpinfo改成类成员变量,而不是在这个函数的局部变量 ”“应该是结构体在内存字节对齐的原因 填充BITMAPINFO结构体的时候可能存在越界 我猜可能是这个 没有测试不好说”
我按照上面的做法,试着把中断的变量定义到类中...还真没错误了。
最终解决方法我是在下面这个网址看到的:
http://topic.csdn.net/u/20090506/12/121d76ad-940a-4ad6-8b93-0c0bf1d80d69.html
由于看不到具体的结构体操作,我想应该是调的库文件的问题,因为是以前的版本,容易出现这样的错误。虽然不知道为什么可以这样解决,但是没有这个问题了,也差不多了,希望对于和我一样的新手有帮助~
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; }
单步调试时,执行res = ::GetDIBits(hdc, bitmap, 0, 1, NULL, &bmpinfo, DIB_RGB_COLORS);
得到的结果是正确的
只是RemoteDisplay函数在返回时弹出那个错误
这个函数是在DLL库里面,这个DLL库的函数目前只写了两个,没有涉及动态内存的申请,只有一个内存映射文件的创建
m_hMsgFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024*1024, mappingFileName);
然后把图像信息写入内存映射文件中,方便其他进程共享。源程序中没有涉及动态内存分配。
-------------------------------------------------------
我改动了这几个地方后测试没有问题
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;
-----------------------------------------------------------
我刚在再试了试,把bmpinfo改成类成员变量,而不是在这个函数的局部变量
int res;
res = ::GetDIBits(hdc, bitmap, 0, 1, NULL, &bmpinfo, DIB_RGB_COLORS);
if(res == 0)
return FALSE;
这些语句任然加上,错误也不会出现。
R:应该是结构体在内存字节对齐的原因 填充BITMAPINFO结构体的时候可能存在越界
--------------------------------------------------------------------------------------------
为什么不用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看仔细了没
-======================================================================
三、
Problem
The following error message occurs when building on Test RealTIme environment with the cvisual7 TDP?
Run-Time Check Failure #2 - Stack around the variable 'xxx' was corrupted.
Cause
Stack pointer corruption is caused writing outside the allocated buffer in stack memeory.
Solution
This kind of error is detected by setting /RTC1 compiler option from menu Project -> Settings -> Configuration properties -> Build -> Compiler -> Compiler flags when using TDP cvisual7 in IBM? Rational? Test RealTime environment.. This enables stack frame run-time error checking. For example, the following code may cause the above error messge.
#include <stdio.h> #include <string.h> #define BUFF_LEN 11 // 12 may fix the Run-Time Check Failure #2 int rtc_option_test(char * pStr); int main() { char * myStr = "hello world"; rtc_option_test(myStr); return 0; } int rtc_option_test(char * pStr) { char buff[BUFF_LEN]; strcpy(buff, pStr); //cause Run-Time Check Failure #2 - Stack around //the variable 'buff' was corrupted. return 0; }