為什麼c++程序中#define max 5000000 太大不能運行?

如果在程序中聲明

int a[max];//不能運行

int* a=new int[max];//可以運行

或者這樣:

在main()之前這樣聲明;

const int max=5000000;

int a[max];//可以運行

但是把 int a[max];放在main()裡面又不能運行了。

真是暈了,求大神詳細講解一下這是為什麼?

另外最近在學演算法,經常在oj上遇到測試量太大不能通過的情況,

如何有效避免這類情況的發生呢?

謝謝。


結論:任何函數裡面不要開大數組。

原因:

寫在main()外面的變數叫做全局變數,分配在靜態數據區。

new出來的變數叫動態變數,分配在堆上。

函數裡面的變數叫局部變數,分配在棧上。

前兩者基本只受你的內存大小影響,想開多大開多大。

棧空間是和操作系統以及編譯器有關的,你用的DevCpp和Windows,那這個限制應該是4MB(如果沒有記錯的話),int[5000000]需要的空間是19MB,所以就放不下(俗稱爆棧),從而就運行錯誤了。

當然,如果你硬是想把這個數組放在函數裡面,可以通過調整編譯選項來達到。

點DevCpp上面的"compiler option", 把這段話貼到"add these commands to compiler"的那個框里:

-Wl,--stack,100000000


當年我還是一個青蔥少年,在寫了1年多C++程序之後,讀了《C++ Primer》,自覺功力大進,睥睨程序,頗為自得。領悟了,(裸)指針這玩意兒能不用就不用等種種道理。因此到哪兒都是開數組。有一日開了一個2M位元組的數組,跟題主一樣,跑到這一行程序立刻崩潰。百思不得騎姐。遍查網路得到一個棧溢出的解釋,方知天外有天,C++萬里長征,才第一步呢。


爆棧

函數里用聲明變數的放在棧里的,棧比較小。而函數外聲明的變數放在全局區,全局區較大。所以大數組還是當做全局變數聲明吧


直接聲明的數組放在棧內存里,動態內存分配的放在堆內存里


這裡存在一個堆(heap)空間與棧(stack)空間的問題。嚴格說這是OS管理的範疇。

stack是程序準備運行時,OS分配給它的一片連續內存區域。stack在執行期總大小不變,對於C/C++在編譯時就會指定申請的棧空間大小,一般都不會很大,並且系統也不允許棧空間太大,因為棧空間必須要連續一整塊,申請不到則這個進程不可啟動。

堆空間則是OS管理內存的公共區域,空間申請都在執行期,申請不到最多拋個異常(C里直接返回個null),空間很大,而且不必要以線程為單位連續,自然可以開更大的數組。

另外以我多年的ACM/OI經驗來看,一般題目用棧空間都不會有太大問題,換句話說就是沒必要非要開那麼大個數組。如果實在不夠用,大部分情況是你的方法錯了或者有明顯優化你沒用到……


棧容量比堆小很多 這麼干就爆棧了


傳說中的爆棧工程師。


main()函數使用的是棧空間,大小好像為1M左右,new方法分配的是堆空間,在內存中,可以分到G以上的內存空間。建議你去看看c++的內存管理機制。


想起前些天某大哥的程序,new了10M,結果死活進不了線程!


不要混合c進去,不要用宏!!!!


全局變數還有new出來的數組都是建立在堆上的,堆的最大大小與系統內存有關,而函數里直接分配也是在棧上的,windows下的棧可能系統允許的很小,於是開不下。


一個程序四個segment(以前也有說3個的), code, stack, heap, data. static的放在了data里(你在函數外申明也應該是在data里),new的放在了heap里,直接寫的放在了stack上。stack本身不會太大,如果你知道runtime stack怎麼回事也就知道往stack上堆太多東西的風險以及影響效率。


linux下沒問題

----------------------

回復 Mio Yuan :linux用戶空間棧在發生缺頁中斷時可以自動擴展的。棧大小隻受物理內存限制


vector& a;


推薦閱讀:

為什麼有些人會覺得一個總是讓程序員加班的公司是可能以工程文化為中心的呢?
為什麼易語言老是被人家說的一無是處?
如何編程產生泊松分布的隨機數?
你在學習 C++ 的過程中遇到的最大的困難是什麼?
作為一名程序員,你在編程的道路上一路走來都接觸過什麼語言?對你的程序員之路有什麼影響?

TAG:演算法 | 編程 | C | 數據結構 |