編譯程序目標代碼運行時的存儲區
A. 問一個較為老的問題,C++程序運行時內存分為幾個區域
一個由C/C++編譯的程序佔用的內存分為以下幾個部分
1、棧區(stack)— 程序運行時由編譯器自動分配,存放函數的參數值,局部變數的值等。其操作方式類似於數據結構中的棧。程序結束時由編譯器自動釋放。
2、堆區(heap) — 在內存開辟另一塊存儲區域。一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。
3、全局區(靜態區)(static)—編譯器編譯時即分配內存。全局變數和靜態變數的存儲是放在一塊的,初始化的 全局變數和靜態變數在一塊區域, 未初始化的全局變數和未初始化的靜態變數在相鄰的另一塊區域。 - 程序結束後由系統釋放
4、文字常量區 —常量字元串就是放在這里的。 程序結束後由系統釋放
5、程序代碼區—存放函數體的二進制代碼。
B. 一個程序編譯完成後在內存中是如何存儲的
如上所說,內存被分成 程序代碼區、堆區、棧區 還有個全局數據區
1.程序代碼區:存放你的全部代碼
2.堆區:存放用new 申請的變數(如 int a = new int(5))
3.棧區;存放int = 5;之類的變數(必須放在函數中)
4.全局數據區:存放全局或靜態變數,即定義在函數外的,或加上static的變數
(如:static int a = 5;)
C. C或C++程序編譯時內存分為哪5個存儲區呢
我想很多人也是糊塗,以下文章寫得很好,故全文轉來,慢慢體會。 程序的內存分配(堆和棧區別) 一、預備知識 程序的內存分配 一個由c/C++編譯的程序佔用的內存分為以下幾個部分 1、棧區(stack) 由編譯器自動分配釋放 ,存放函數的參數值,局...
D. c#程序運行時內存分為哪幾個區
一、內存基本構成
可編程內存在基本上分為這樣的幾大部分:靜態存儲區、堆區和棧區。他們的功能不同,對他們使用方式也就不同。
靜態存儲區:內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。它主要存放靜態數據、全局數據和常量。
棧區:在執行函數時,函數內局部變數的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,但是分配的內存容量有限。
堆區:亦稱動態內存分配。程序在運行的時候用malloc或new申請任意大小的內存,程序員自己負責在適當的時候用free或delete釋放內存。動態內存的生存期可以由我們決定,如果我們不釋放內存,程序將在最後才釋放掉動態內存。 但是,良好的編程習慣是:如果某動態內存不再使用,需要將其釋放掉,否則,我們認為發生了內存泄漏現象。
二、三者之間的區別
我們通過代碼段來看看對這樣的三部分內存需要怎樣的操作和不同,以及應該注意怎樣的地方。
例一:靜態存儲區與棧區
char* p = 「Hello World1」;
char a[] = 「Hello World2」;
p[2] = 『A』;
a[2] = 『A』;
char* p1 = 「Hello World1;」
這個程序是有錯誤的,錯誤發生在p[2] = 『A』這行代碼處,為什麼呢,是變數p和變數數組a都存在於棧區的(任何臨時變數都是處於棧區的,包括在main()函數中定義的變數)。但是,數據「Hello World1」和數據「Hello World2」是存儲於不同的區域的。
因為數據「Hello World2」存在於數組中,所以,此數據存儲於棧區,對它修改是沒有任何問題的。因為指針變數p僅僅能夠存儲某個存儲空間的地址,數據「Hello World1」為字元串常量,所以存儲在靜態存儲區。雖然通過p[2]可以訪問到靜態存儲區中的第三個數據單元,即字元『l』所在的存儲的單元。但是因為數據「Hello World1」為字元串常量,不可以改變,所以在程序運行時,會報告內存錯誤。並且,如果此時對p和p1輸出的時候會發現p和p1裡面保存的地址是完全相同的。換句話說,在數據區只保留一份相同的數據(見圖1-1)。
例二:棧區與堆區
char* f1()
{
char* p = NULL;
char a;
p = &a;
return p;
}
char* f2()
{
char* p = NULL:
p =(char*) new char[4];
return p;
}
這兩個函數都是將某個存儲空間的地址返回,二者有何區別呢?f1()函數雖然返回的是一個存儲空間,但是此空間為臨時空間。也就是說,此空間只有短暫的生命周期,它的生命周期在函數f1()調用結束時,也就失去了它的生命價值,即:此空間被釋放掉。所以,當調用f1()函數時,如果程序中有下面的語句:
char* p ;
p = f1();
*p = 『a』;
此時,編譯並不會報告錯誤,但是在程序運行時,會發生異常錯誤。因為,你對不應該操作的內存(即,已經釋放掉的存儲空間)進行了操作。但是,相比之下,f2()函數不會有任何問題。因為,new這個命令是在堆中申請存儲空間,一旦申請成功,除非你將其delete或者程序終結,這塊內存將一直存在。也可以這樣理解,堆內存是共享單元,能夠被多個函數共同訪問。如果你需要有多個數據返回卻苦無辦法,堆內存將是一個很好的選擇。但是一定要避免下面的事情發生:
void f()
{
…
char * p;
p = (char*)new char[100];
…
}
這個程序做了一件很無意義並且會帶來很大危害的事情。因為,雖然申請了堆內存,p保存了堆內存的首地址。但是,此變數是臨時變數,當函數調用結束時p變數消失。也就是說,再也沒有變數存儲這塊堆內存的首地址,我們將永遠無法再使用那塊堆內存了。但是,這塊堆內存卻一直標識被你所使用(因為沒有到程序結束,你也沒有將其delete,所以這塊堆內存一直被標識擁有者是當前您的程序),進而其他進程或程序無法使用。我們將這種不道德的「流氓行為」(我們不用,卻也不讓別人使用)稱為內存泄漏。這是我們C++程序員的大忌!!請大家一定要避免這件事情的發生。
總之,對於堆區、棧區和靜態存儲區它們之間最大的不同在於,棧的生命周期很短暫。但是堆區和靜態存儲區的生命周期相當於與程序的生命同時存在(如果您不在程序運行中間將堆內存delete的話),我們將這種變數或數據成為全局變數或數據。但是,對於堆區的內存空間使用更加靈活,因為它允許你在不需要它的時候,隨時將它釋放掉,而靜態存儲區將一直存在於程序的整個生命周期中。
我們此專題僅僅是簡要的分析了內存基本構成以及使用它們時需要注意的問題。對內存的分析和討論將一直貫穿於我們以後所有的專題,這也就是為什麼把它作為第一講的原因。
E. 編譯時分配內存和運行時分配內存
編譯其實只是一個掃描過程,進行詞法語法檢查,代碼優化而已,編譯程序越好,程序運行的時候越高效。
我想你說的「編譯時分配內存」是指「編譯時賦初值」,它只是形成一個文本,檢查無錯誤,並沒有分配內存空間。
當你運行時,系統才把程序導入內存。一個進程(即運行中的程序)在主要包括以下五個分區:
棧、堆、bss、data、code
代碼(編譯後的二進制代碼)放在code區,代碼中生成的各種變數、常量按不同類型分別存放在其它四個區。系統依照代碼順序執行,然後依照代碼方案改變或調用數據,這就是一個程序的運行過程。
F. C或C++程序編譯時內存分為幾個存儲區
1、從操作系統原理的角度來看,只有一個存儲區就是虛擬內存。
2、根據功能可以分為 ,棧區 、堆區、靜態區, 棧區一般指的一個函數局部變數,在編譯原理中這叫做一個棧幀。 堆區一般是為了用戶自由分配的,一般C語言中用MALLOC函數分配,C++中用NEW運算符來分配,它是有操作系統的堆管理器來管理的,拿windows來說,在一個程序運行後,一般至少有兩個默認的堆,一個是new堆,一個進程 自己的堆, 靜態區,這個一般是全局變數或者static變數使用的區域,這個區域,如果你對PE結構熟悉,就會明白這實際上是pe 區段中的.data區段,當程序運行後變成進程,這個區段是直接內存文件映射過去的。
G. 當計算機執行某一程序時,其運行時程序段應存儲在__ 內存嗎為什麼
一共六個不同的地方存儲數據:
寄存器(在CPu里,內存地址訪問) 堆棧 堆 靜態存儲 常量存儲 非RAM存儲
程序運行時,系統將為程序分配一塊存儲空間
目標程序區:用來存放目標代碼
靜態數據區:用來存放編譯時就能確定存儲空間的數據
運行棧區:用來存放運行時才能確定存儲空間的數據
運行堆區:用來存放運行時用戶動態中請存儲空間的數據。
H. C程序的內存分為5個區域:(棧區), (堆區), (數據區), 代碼區,文字常量區。
不是的,上述五個區域指的是C程序運行時所可能涉及的區域。
I. C++程序運行時的內存空間如何分區
C++程序的內純格局通常分為4個區:
1.數據區(Data Area)
2.代碼區(Code Area)
3.棧區(Stack Area)
4.堆區(即自由存儲區)(Heap Area)
全局變數、靜態變數、常量存放在數據區,所有類成員函數和非成員函數代碼存放在代碼區,為運行函數而分配的局部變數、函數參數、返回數據、返回地址等存放在棧區,餘下的空間為堆區。
因為堆是有限的,它可能變得擁擠,如果堆中沒有足夠的自由空間以滿足內存的需要時,那麼此需要失敗,並且返回一個空指針。因此,必須在使用NEW生成的指針之前進行檢查,方法如下:
C++代碼
HeapClass *pa1 , *pa2;
pa1 = new HeapClass(4); // 分配空間
pa2 = new HeapClass (); // 分配空間
if(!pa1 || !pa2){ // 檢查空間
cout<<"out of Memory"<<endl;
return;
}
HeapClass *pa1 , *pa2;
pa1 = new HeapClass(4); // 分配空間
pa2 = new HeapClass (); // 分配空間
if(!pa1 || !pa2){ // 檢查空間
cout<<"out of Memory"<<endl;
return;
}
一般來說,堆空間相對其他內存空間比較空閑,隨要隨拿,給程序運行帶來了較大的自由度,但是管理堆區是一件十分復雜的工作,頻繁地分配(NEW)和釋放(DELETE)不同大小的堆空間將會產生堆內碎塊。使用堆空間往往由於:
.直到運行時才能知道需要多少對象空間;
.不知道對象的生存期到底有多長;
.直到運行時才知道一個對象需要多少內存空間;
J. C++程序運行過程中,各種類型的數據都是怎麼存儲的,主要存儲在哪些空間里
有5大存儲區域:
1:堆區 主要是用戶自己申請的內存,如new 運算符申請的內存空間
2:棧區 先進後出的存儲結構,局部變數,函數的調用,等
3:靜態存儲區 放局部,全局的靜態變數,和全局的變數 生命周期是整個應用程序
4:寄存器 系統調用
5:程序代碼區 你寫的代碼也需要放在內存中!