大家都知道,Windows程序的內存機制大概是這樣的,全局變量(局部的靜態變量本質也屬於此范圍)存儲於堆內存,該段內存較大,一般不會溢出; 函數地址、函數參數、局部變量等信息存儲於棧內存,VC6中棧內存默認大小為1M,對於當前日益擴大的程序規模而言,稍有不慎就可能出問題。
(動態申請的內存即new出來的內存不在棧中)
即如果函數這樣寫:
void test_stack_overflow()
{
char* chdata = new[2*1024*1024];
delete []chdata;
}
是不會出現這個錯誤的,而這樣寫則不行:
void test_stack_overflow()
{
char chdata[2*1024*1024];
}
大多數情況下都會出現內存溢出的錯誤,不信在vc6中隨便做個程序,調用一下這個函數試式。
出現棧內存溢出的常見原因有2個:
1> 函數調用層次過深,每調用一次,函數的參數、局部變量等信息就壓一次棧。
2> 局部靜態變量體積太大
第一種情況不太常見,因為很多情況下我們都用其他方法來代替遞歸調用(反正我是這么做的),所以只要不出現無限制的調用都應該是沒有問題的,起碼深度幾十層我想是沒問題的,這個我沒試過但我想沒有誰會把調用深度作那么多。檢查是否是此原因的方法為,在引起溢出的那個函數處設一個斷點,然后執行程序使其停在斷點處, 然后按下快捷鍵Alt+7調出call stack窗口,在窗口中可以看到函數調用的層次關系。
第二種情況比較常見了,我就是犯了這個錯誤,我在函數里定義了一個局部變量,是一個類對象,該類中有一個大數組,大概是1.5M。
解決辦法大致說來也有兩種:
1> 增加棧內存的數目
2> 使用堆內存
增加棧內存方法如下,在vc6種依次選擇Project->Setting->Link,在Category中選擇output,在Reserve中輸入16進制的棧內存大小如:0x10000000,然后點ok就可以了。
其他編譯器也有類似的設置,個人認為這不是一個好辦法,有一個致命原因,不知道有沒有人遇到過,我把棧內存改大后,與數據庫建立不了連接了(ADO方式,Acess數據庫),把棧內存還原,問題立刻消失。不知道究竟是什么原因,有知道的可以告訴我。
第二種解決辦法是比較可行的,具體實現由很多種方法可以直接把數組定義改成指針,然后動態申請內存;也可以把局部變量變成全局變量,一個偷懶的辦法是直接在定義前邊加個static,呵呵,直接變成靜態變量(實質就是全局變量)。即可以把上例中的函數這么寫:
void test_stack_overflow()
{
static char chdata[2*1024*1024];
}
當然,除非萬不得已,盡量不要使用這么大的數組,出現這種情況多半說明程序結構有問題。
============================
棧溢出了。棧的默認大小1M,超過就出問題了。
如果不是函數調用太深,一直不退出,就是棧上變量太大,太多。比如:
char arr[1024][1024]; //直接耗了1M
============================
VC定義超大數組時,stack OverFlow的解決方法,當然了這里的數組不僅僅是int,char,double等內置類型,還可以是其他的類,如CString,CButton,CMap等。
stack overflow,堆棧溢出
VC超大數組Stack Overflow的解決方法
這次在寫一個程序的時候,定義了一個超大的char型數組,元素個數超過3000W個的時候,程序無法調試,提示:Stack Overflow。
用單步調試試了一下,定義數組的時候沒問題,但是在開始對數組賦值的時候,就會彈出一個Stack OverFlow的錯誤提示,有了程序的錯誤提示,那就好解決了,在百度上搜索了一下,就找到了解決方法.
如果是英文版:
project -> setting -> link -> category 選擇 output -> stack allocations 里面的 reserve 填入 0x10000000 然后選OK
當然了,如果還是不能解決的話,那就要用動態數組了,畢竟動態意味着無窮~~
vc動態數組實現
-------------------------------------------
棧被用作存放局部變量、調用函數前存放返回地址等,vc中每個工程默認棧大小為1m,new分配的空間不在棧(stack)中,在堆(heap)中,因此不會是由於new了不delete造成的。棧溢出可能的原因是:生成了大量局部變量或使用了大的局部數組、遞歸函數設計不當無出口導致一直調用無法返回。可以修改棧的大小解決這個問題,修改方式如下:
LINK的/STACK選項 :Project-->settings->link->category選output-->
/STACK :reserve[,commit]
reserve:棧總大小
commit:程序開始時系統提供的實際內存量
缺省:1M,8K
參數為0取缺省值
【reserve :2000000 棧被設置為2M 】