天天看點

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

今天悲催的接二連三的出現這個錯誤,我查檢視自己對話框類中的變量,都初始化了,最終在自己在對話框引入的類中發現,自己在其構造函數中初始化了一個字元數組變量,并且沒有用過,去掉之後問題得到解決了。本人不建議重建工程就好了這種說法,這個肯定是作者無意識的在第二次重建中把一些為指派得的變量賦了值,不到萬不得已建議不要重建

反思:

   有時候對話框崩潰不一定是它本身有什麼變量未初始化,有可能是你自己引入的其他類有未初始化的現象。對自己定義的類和變量一定要合理的管理

查到的關于這個錯誤的一些解決辦法

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/[email protected]/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得機制)。