Run-Time Check Failure #2 - Stack around the variable 'dlg1' was corrupted.

来源:互联网 发布:大学英语教材听力软件 编辑:程序博客网 时间:2024/06/14 04:35

今天悲催的接二连三的出现这个错误,我查查看自己对话框类中的变量,都初始化了,最终在自己在对话框引入的类中发现,自己在其构造函数中初始化了一个字符数组变量,并且没有用过,去掉之后问题得到解决了。本人不建议重建工程就好了这种说法,这个肯定是作者无意识的在第二次重建中把一些为赋值得的变量赋了值,不到万不得已建议不要重建


反思:

   有时候对话框崩溃不一定是它本身有什么变量未初始化,有可能是你自己引入的其他类有未初始化的现象。对自己定义的类和变量一定要合理的管理



查到的关于这个错误的一些解决办法


http://hi.baidu.com/qinzhispace/item/af1b14cc1785b33598b498a1

可能会有以下几种情况:
一、 strcpy、memcpy、strncpy、stpcpy、bcopy等拷贝区的大小不匹配,引起冲突或溢出造成的。
例如:
void myfun()
{
char mybuf[10]; 
strcpy(mybuf, "This is definitely more than 10 characters long, it will also cause a Run-Time Check");
}
二、当使用 memset/ZeroMemory初始化数据结构体 structure或数组 array时,由于大小设置错误引起的。例如:struct MyStruct
{
int var;
};
void myfun2()
{
MyStruct ms;
ZeroMemory(&ms, 20); //since MyStruct is only one variable in the struct this will cause problems
}
三、可能是指针移动,指向错误,例如: 
void myfun3()
{
int a;
int*b = &a; 
a++;
*a = 20;
}
四、可能是使用了itoa一类的函数,造成目标区与初始定义的大小不一致了。
如:
oid myfun4()
{
int b=54698369;
char ch1[8];
itoa(b,ch,16);
}
总之,出现这类错要仔细检查提示错误的变量variable "s",将其大小修改为匹配。
如四中:
Run-Time Check Failure #2 - Stack around the variable 'ch1' was corrupted,提示错误的变量variable "ch1",将它增加一个空间作为终止记号的存放处:
void myfun4()
{
int b=54698369;
char ch1[9];
itoa(b,ch,16);
ch1[8]='\0';
}
五:还有可能是变量赋值了,但是变量没有找到


二  

  http://blog.163.com/liling2009@126/blog/static/7765560320116435821487/

创建了一个MFC基于Dialog(对话框)的程序,编译通过,运行程序也正常,但是在退出时出现这个错误并跳出调试窗口: 

有人在百度上找到:

m_pMainWnd = &dlg错误解决方法
本身是个莫名其妙的错误,现象就是运行时连弹N个错误框,调试时到m_pMainWnd = &dlg这一句出现异常,而这一句其实是VC生成的。一般出现这种错误的原因是在工程的主窗口新添加了成员变量,只要REBUILD ALL一下,解决了吧。

我“清理”后,重新生成,然后运行程序,发现确实不出现这个错误了。

网上也有人说是,内存访问越界。内存访问越界的后果是:你的写入破坏了本不属于你的空间。
具体是什么原因导致该错误的发生,目前还是不清楚

三 

  http://bbs.csdn.net/topics/330260078

. 原理分析
经常有些新C++程序员问:C++的类的成员个数是不是有限制,为什么我加一个变量后程序就死了?或者说:是不是成员变量的顺序很重要,为什么我两个成员变量顺序换一换程序就不行了?凡此种种之怪现象,往往都是内存访问越界所致。

何谓内存访问越界,简单的说,你向系统申请了一块内存,在使用这块内存的时候,超出了你申请的范围。例如,你明明申请的是100字节的空间,但是你由于某种原因写入了120字节,这就是内存访问越界。内存访问越界的后果是:你的写入破坏了本不属于你的空间。

下面是一个简单的例子:
int a;
char b[16]="abcd";
int c;

a = 1;
c = 2;
printf("a=%d,c=%d\n", a,c);
memset(b, 0,32); //注意这里访问越界了,你只有16字节空间,却修改了32字节
printf("a=%d,c=%d\n", a,c);

你可以看出,在memset前后,两个printf语句打印出来的值并不一样,因为memset越界后修改了a或者c的值(由于不同编译器对变量在空间中顺序的安排可能有不同策略,因此我用两个变量,希望能抓到越界信息。对于VC,debug模式下系统添加了很多填充字节,你可能需要增加越界的数量才能看到效果)


2. 为什么增加一个变量后程序就崩溃了?
增加一个变量后,内存中变量的布局也发生了变化。如果一个内存越界破坏了一个不含指针的结构,程序虽然逻辑不对,但是不至于崩溃。但是如果增加变量后,内存访问越界破坏了一个指针,则会导致程序崩溃。

例如:

int a;
char b[128];
//bool c;
char* d=new char[128];
int e;

b[136] = '\0';
b[137] = '\0';
b[138] = '\0';
b[139] = '\0';
strcpy(d, "haha");
注意, b访问越界了8个字节位置处的4个字节。如果没有c,那么越界破坏了e变量,不会导致程序崩溃。但是加上c之后,破坏的变量可能就是d了,由于指针被破坏后,一旦访问就是内存访问违例,导致程序崩溃。

这也解释了为什么交换顺序会导致程序崩溃。如果上面情况没有变量c,你交换e和d,结构也是类似的,程序也一样要崩溃。

3. 为什么有些情况越界了程序也没错?
这主要是说这个话的人对什么是“错”没有正确的认识。程序不是只有崩溃了才是错!你破坏了别的变量,那个变量总有被使用的时候,尽管那个变量不会导致诸如程序崩溃、报警之类的严重错误,但是其计算结果必然是错误的。你说“程序没错”,是因为你根本没有发现错误而已。这种情况甚至比程序直接崩溃还要恶劣,因为程序一旦崩溃你肯定会去查,可以在导致真正严重的问题之前就把问题解决了。而如果计算错误隐藏到很晚,你的损失就可能很大了。(例如,一颗卫星上天了,你才发现一台仪器由于软件故障无法测量真正的数据,那得多少损失?)

4. 如何解决内存访问越界问题?
老实说没有好的方法。遇到这种问题,首先你得找到哪里有内存访问越界,而一个比较麻烦得问题在于,出现错误得地方往往不是真正内存越界得地方。对于内存访问越界,往往需要进行仔细得代码走查、单步跟踪并观察变量以及在调试环境得帮助下对变量进行写入跟踪(如VC6就有一旦变量被修改就break得机制)。