關於C 語言的內存分配問題

      我們在做題時開數組經常會出現爆棧問題,那麼這是爲什麼?

      讓我們帶着問題先來了解一下C語言的內存分區,C語言內存分爲個區:

代碼區:顧名思義這裏是用來存儲代碼編譯後的二進制機器碼;

堆區:用於動態內存分配,一般由程序員分配或釋放,如果程序員沒有在程序運行中手動釋放,那麼會在程序結束後釋放。

棧區:編譯器自動分配和釋放,一般用來存放局部變量、函數參數。

全局初始化數據區/靜態數據區(Data Segment):用來存儲全局變量和靜態變量。

 ⑤未初始化數據區(BSS):在運行時改變值。改變值(初始化)的時候,會根據它是全局變量還是局部變量,進到他們該去的區。否則會持續待在BSS裏面與世無爭。(待會兒會用實驗來證明並感受它的存在。)

       重點說一下棧區全局初始化數據區/靜態數據區 我們常說的爆棧問題,大部分就是發生在了棧區,爆棧原因是我們定義了過大的數組棧區內存裝不下了。那麼我們把數組定義在了 main() 外面(也就是全局區)一般情況下不會爆棧,爲什麼?

      原因很簡單 那就是在Windows下C語言分配給棧區的內存遠小於全局區,全局區的內存與電腦的剩餘內存有關,我們做題所定義的變量佔用的內存簡直就是小兒科,但是!!!分配給棧區的內存只有 2M(接近2M) !也就是說 。。。

先說一下計算機常用內存單位之間的換算 :

                                         1 M = 1024 KB ;1 KB = 1024Byte ; 1Byte = 8 bit

繼續說:也就是說棧區只有 2 * 1024 *1024 = 2,097,152 字節  僅能儲存 524,288 個int型變量(其實也不少了);但是在創建二維數組時要小心了 最大隻能創建 int array[719][720] 的二維數組,否則 會爆棧;

那麼爲什麼要把變量存儲在棧區?直接儲存在全局區多好?我們要這樣想 它存在肯定有它存在的理由,經過查詢:

      棧:由系統自動分配,速度較快。但程序員是無法控制的。

      堆:是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便。

經過以上的探討對C語言的內存分配有所瞭解了,再講一個小知識點(BSS區):先看一段代碼:

#include<stdio.h>
int main (){
	int array[518156]; 
	printf("sucess!\n");
	return 0;
} 

經過測試array[518156];這是我的電腦在棧區所能定義的最大整型數組(再增加一個都不行);

理論上說這時的棧區已經滿了不能再增加變量了,再看下一段代碼:

#include<stdio.h>
int main (){
	int array[518156];
	int test1,test2,test3,test4,test5,test6;

	double test7,test8,test9;

	float test10,test11,test12;

	char test13,test14,test15;

	printf("sucess!\n");
	return 0;
} 

      我在下面又定義了 6 個int 變量,3 個 double 變量,3 個 float 變量,3 個 char 變量 它還是沒爆棧,爲什麼?

原因是 未賦值的 變量存儲在了 BSS區 並未佔用棧內存,當你 給任意個 變量(即使是最小的 char 變量) 賦了值 就會爆棧。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章