chenyujing1234的专栏

有总结才有进步

Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted 解决方法

 

 

一、数据越界

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;
}


 

改一下 project->配置属性->c/c++->代码生成->基本运行时检查 为
默认值 就不会报 那个异常
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭