❶ 變數與內存分配
每種變數都有自己的儲存區,和其他互不關聯
外部變數是存在 靜態區的
自動變數是存在 棧區的
而malloc分配的空間是存放在 堆 中的,
所以malloc只可以管理 堆 中變數,無法管理其他變數的
❷ 全局變數在編譯時怎麼分配空間
關於這個問題,全局變數(成員變數)是在創建對象的時候分配內存的創建對象過程為1分配空間2遞歸的創建父類對象(無父類這步可省略)3初始化成員變數4調用構造方法創建一個對象
靜態變數是在類載入的時候分配空間的,靜態變數和對象沒有關系是在jvm第一次讀到一個類的時候載入信息的過程中分配空間的類載入過程為1載入父類(如果父類已經載入過,則不在載入)2初始化靜態屬性3按順序的初始化靜態代碼塊
初始化的前提就是分配空間
而且靜態變數在以後的創建對象的時候不在初始化所以一般用靜態來保存共享信息
希望對你有所幫助
❸ 操作系統執行可執行程序時,內存分配是怎樣的
在操作系統中,一個進程就是處於執行期的程序(當然包括系統資源),實際上正在執行的程序代碼的活標本。那麼進程的邏輯地址空間是如何劃分的呢?
圖1做了簡單的說明(Linux系統下的):
圖一
左邊的是UNIX/LINUX系統的執行文件,右邊是對應進程邏輯地址空間的劃分情況。
一般認為在c中分為這幾個存儲區: 1. 棧 --有編譯器自動分配釋放 2. 堆 -- 一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收 3. 全局區(靜態區) -- 全局變數和靜態變數的存儲是放在一塊的,初始化的全局變數和靜態變數在一塊區域,未初始化的全局變數和未初始化的靜態變數在相鄰的另一塊區域。程序結束釋放。 4. 另外還有一個專門放常量的地方。程序結束釋放。 在函數體中定義的變數通常是在棧上,用malloc, calloc, realloc等分配內存的函數分配得到的就是在堆上。在所有函數體外定義的是全局量,加了static修飾符後不管在哪裡都存放在全局區(靜態區),在所有函數體外定義的static變數表示在該文件中有效,不能extern到別的文件用,在函數體內定義的static表示只在該函數體內有效。另外,函數中的"adgfdf"這樣的字元串存放在常量區。比如:代碼:
int a = 0; //全局初始化區
char *p1; //全局未初始化區
main(){
int b; //棧
char s[] = "abc"; //棧
char *p2; //棧
char *p3 = "123456"; //123456 在常量區,p3在棧上。
static int c = 0; //全局(靜態)初始化區
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);//分配得來得10和20位元組的區域就在堆區。
strcpy(p1, "123456");//123456 放在常量區,編譯器可能會將它與p3所指向 的"123456"優化成一塊。
}
還有就是函數調用時會在棧上有一系列的保留現場及傳遞參數的操作。 棧的空間大小有限定,vc的預設是2M。棧不夠用的情況一般是程序中分配了大量數組和遞歸函數層次太深。有一點必須知道,當一個函數調用完返回後它會釋放該函數中所有的棧空間。棧是由編譯器自動管理的,不用你操心。 堆是動態分配內存的,並且你可以分配使用很大的內存。但是用不好會產生內存泄漏。並且頻繁地malloc和free會產生內存碎片(有點類似磁碟碎片),因為c分配動態內存時是尋找匹配的內存的。而用棧則不會產生碎片。 在棧上存取數據比通過指針在堆上存取數據快些。 一般大家說的堆棧和棧是一樣的,就是棧(stack),而說堆時才是堆heap. 棧是先入後出的,一般是由高地址向低地址生長。
堆(heap)和堆棧(stack)的區別
2.1申請方式stack:由系統自動分配。 例如,聲明在函數中一個局部變數 int b; 系統自動在棧中為b開辟空間heap:需要程序員自己申請,並指明大小,在c中malloc函數
如p1 = (char *)malloc(10);
在C++中用new運算符
如p2 = (char *)malloc(10);
但是注意p1、p2本身是在棧中的。
2.2 申請後系統的響應棧:只要棧的剩餘空間大於所申請空間,系統將為程序提供內存,否則將報異常提示棧溢出。堆:首先應該知道操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,會遍歷該鏈表,尋找第一個空間大於所申請空間的堆結點,然後將該結點從空閑結點鏈表中刪除,並將該結點的空間分配給程序,另外,對於大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣,代碼中的delete語句才能正確的釋放本內存空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閑鏈表中。
2.3
2.4申請效率的比較:棧由系統自動分配,速度較快。但程序員是無法控制的。堆是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便.另外,在WINDOWS下,最好的方式是用VirtualAlloc分配內存,他不是在堆,也不是在棧是直接在進程的地址空間中保留一快內存,雖然用起來最不方便。但是速度快,也最靈活。
2.5堆和棧中的存儲內容棧: 在函數調用時,第一個進棧的是主函數中後的下一條指令(函數調用語句的下一條可執行語句)的地址,然後是函數的各個參數,在大多數的C編譯器中,參數是由右往左入棧的,然後是函數中的局部變數。注意靜態變數是不入棧的。當本次函數調用結束後,局部變數先出棧,然後是參數,最後棧頂指針指向最開始存的地址,也就是主函數中的下一條指令,程序由該點繼續運行。堆:一般是在堆的頭部用一個位元組存放堆的大小。堆中的具體內容有程序員安排。
2.6存取效率的比較
char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在運行時刻賦值的;
而bbbbbbbbbbb是在編譯時就確定的;
但是,在以後的存取中,在棧上的數組比指針所指向的字元串(例如堆)快。
比如:#include <...>
void main(){
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
對應的匯編代碼
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一種在讀取時直接就把字元串中的元素讀到寄存器cl中,而第二種則要先把指針值讀到edx中,在根據edx讀取字元,顯然慢了。
2.7小結:堆和棧的區別可以用如下的比喻來看出:使用棧就象我們去飯館里吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等准備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。使用堆就象是自己動手做喜歡吃的菜餚,比較麻煩,但是比較符合自己的口味,而且自由度大。堆和棧的區別主要分:操作系統方面的堆和棧,如上面說的那些,不多說了。還有就是數據結構方面的堆和棧,這些都是不同的概念。這里的堆實際上指的就是(滿足堆性質的)優先隊列的一種數據結構,第1個元素有最高的優先權;棧實際上就是滿足先進後出的性質的數學或數據結構。雖然堆棧,堆棧的說法是連起來叫,但是他們還是有很大區別的,連著叫只是由於歷史的原因。
申請大小的限制棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在 WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。一、預備知識—程序的內存分配一個由c/C++編譯的程序佔用的內存分為以下幾個部分
1、棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變數的值等。其操作方式類似於數據結構中的棧。2、堆區(heap)— 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。3、全局區(靜態區)(static)—全局變數和靜態變數的存儲是放在一塊的,初始化的全局變數和靜態變數在一塊區域, 未初始化的全局變數和未初始化的靜態變數在相鄰的另一塊區域。 - 程序結束後有系統釋放4、文字常量區 —常量字元串就是放在這里的。 程序結束後由系統釋放5、程序代碼區(text)—存放函數體的二進制代碼。
❹ 究竟是什麼決定了指針變數是4個位元組,電腦的內存分為哪幾部分啊,可以具體介紹介紹
(1)CPU在單位時間內(同一時間)能一次處理的二進制數的位數叫字長。計算機處理數據的速率,和它一次能加工的位數以及進行運算的快慢有關。
(2)指針,是一個無符號整數(unsigned int),它是一個以當前系統定址范圍為取值范圍的整數。一般的CPU、windows操作系統、VC++都是32位的,所以指針變數是4個位元組。
❺ 計算機內存可以分為哪些區%
為你解答如下:
一個由
C/C++編譯的程序佔用的內存分為以下幾個部分
1、棧區(stack)—由編譯器自動分配釋放,存放函數的參數值,局部變數的值等。其操作方式類似於數據結構中的棧。
2、堆區(heap)—一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。
3、全局區(靜態區)(static)—,全局變數和靜態變數的存儲是放在一塊的,初始化的全局變數和靜態變數在一塊區域,未初始化的全局變數和未初始化的靜態變數在相鄰的另一塊區域。
- 程序結束後由系統釋放。
4、文字常量區—常量字元串就是放在這里的。程序結束後由系統釋放
5、程序代碼區—存放函數體的二進制代碼。
❻ 內存空間具體是指什麼啊,為一個變數分配存儲空間是什麼意思,怎麼分配啊
你定義一個變數就是為變數在內存中分配了存儲空間(單元),變數的類型不同所分配的存儲空間也不同,比如整型,長整型,單精度型,雙精度型,所佔用的存儲空間都不同,
❼ 定義變數 占內存的多少
一個指針變數在內存中占兩個位元組(small模式編譯)
一個指針變數在內存中佔四個位元組(32位機器上)
一般都是32位機器的,所以四個位元組咯。
❽ 變數是放在了堆內存還是棧內存
變數分為靜態變數、動態變數。
靜態變數在操作系統裝載程序時分配固定的數據空間;
程序運行期間的動態變數佔用堆內存;
子程序內部定義的變數一般佔用棧空間。
❾ c語言問題。關於變數內存分配
變數由編譯器分配空間
變數的地址不是連續分配的是因為內存對齊
C99規定int、unsigned int和bool可以作為位域類型,但編譯器幾乎都對此作了擴展,允許其它類型類型的存在。
使用位域的主要目的是壓縮存儲,其大致規則為:
1) 如果相鄰位域欄位的類型相同,且其位寬之和小於類型的sizeof大小,則後面的欄位將緊鄰前一個欄位存儲,直到不能容納為止;
2) 如果相鄰位域欄位的類型相同,但其位寬之和大於類型的sizeof大小,則後面的欄位將從新的存儲單元開始,其偏移量為其類型大小的整數倍;
3) 如果相鄰的位域欄位的類型不同,則各編譯器的具體實現有差異,VC6採取不壓縮方式,Dev-C++採取壓縮方式;
4) 如果位域欄位之間穿插著非位域欄位,則不進行壓縮;
❿ 如何知道一個變數在內存中分配幾個存儲單元
1、棧區(又稱堆棧區)存放函數的參數值、非靜態局部變數等,由編譯器自動分配和釋放,通常在函數執行完後就釋放了,其操作方式類似於數據結構中的棧。棧內存分配運算內置於CPU的指令集,效率很高,但是分配的內存量有限。
2、堆區就是通過malloc動態分配的內存塊,編譯器不會負責它們的釋放工作,需要用程序區釋放,如果不在程序中釋放則一般整個程序結束後會被系統回收內存資源。分配方式類似於數據結構中的鏈表。「內存泄漏」通常說的就是堆區。
3、靜態區(又稱靜態全局區)全局變數和靜態變數的存儲是放在一塊的,初始化的全局變數和靜態變數在一塊區域,未初始化的全局變數和未初始化的靜態變數在相鄰的另一塊區域,所以靜態區又分為兩個段(data、bss後文詳細解釋)。程序結束後,由系統釋放。
4、代碼區存放代碼的區域
5、文字常量區存放只讀數據,如常量字元串