程序各個段text,data,bss,stack,heap

網上找了一堆資料學習一下,了解這些,

有助于規化程序結構,優化代碼;

使用gcc編譯出來的程序,用size可以查看程序結構和大小,

   1: #size hello
   2: Text data bss dec hex filename
   3: 778  200  4   982 3D6 hello

所以一個可執行的程序文件,結構分三部分:

.text 代碼段,用來存放代碼,一般是只讀的區域;

.data 數據段,用來存放全局初始化變量,常量,以及全局或局部靜態變量,只初始化一次;

.bss? BSS段,用來存放全局未初化數據,用0初始化;

那有人問非全局變量放哪里了?

還有常說的堆和棧呢?

程序在執行時,會產生臨時變量或是函數返回值,

還有函數中動態分配的地址空間,如malloc, new等…

根據這些需求,才需要堆和棧的出現,

所以堆(heap)和棧(Stack)這兩個段是在程序運行時才有.

.stack 棧區,用來存放局部變量,函數的參數,返回值等,由編譯器自動分配釋放;

    ?棧的概念來自數據結構,棧只能在一端操作,所以先入棧的后出,“先進后出”,這種結構保護之前的現場,

    如一個函數被調用后,產生的臨時變量都會存到棧區的頂部,當函數完成后,會自動從頂部將剛使用的數據銷毀;

    另外棧區的地址是從高地址向下增長的;

.heap 堆區,用來動態內存分配,如malloc, new申請的內存,由程序員分配釋放;

    程序中不釋放,則程序結束時,由OS回收;據說這個和數據結構中的堆?沒有什么關系;堆區使用時地址向上增長;

? ?

??

?

以上5部分在內存的位置如下圖,

image

?

執行過程:

代碼區的指令依次執行,代碼由操作碼和操作數組成,操作碼決定是順序執行,還是跳轉,還是循環等;操作數可能是立即數,即具體的數直接包含在代碼中,或者是局部變量,則在棧區分配空間,然后引用該數據地址執行,或者是BSS,DATA段的數據,同樣引用其地址執行;

正因為代碼有不同的操作,所以程序在內存中執行時,才分成不同的區,以便節約空間或訪問方便;對于全局變量和靜態變量,一般不會更改其值,但整個執行過程都需要訪問,就單獨放到一個區進行管理;臨時變量生命周期短,需要頻繁的操作,則統一放到棧區;用戶自由分配使用的空間統一放在堆區,便于管理;

引用網上的例子,

   1: //main.cpp 
   2:  int a = 0;     //a在全局已初始化數據區.data
   3:  char *p1;        //p1在.bss(未初始化全局變量)
   4: main() 
   5: {
   6:     int b;            //b在棧區 .stack
   7:     char s[] = "abc"; //s為數組變量,存儲在棧區,.heap
   8:                       //"abc"為字符串常量,存儲在已初始化數據區
   9:     char *p1,p2;     //p1,p2在棧區
  10:     char *p3 = "123456"; //123456\0在已初始化數據區,p3在棧區
  11:     static int c =0;    //C為全局(靜態)數據,存在于已初始化數據區
  12:                         //另外,靜態數據會自動初始化
  13:     p1 = (char *)malloc(10);//分配得來的10個字節的區域在堆區
  14:     p2 = (char *)malloc(20);//分配得來的20個字節的區域在堆區
  15:     //注意p1,p2是局部變量,所以存儲在棧中,10Byte空間在堆中;
  16:     free(p1);
  17:     free(p2);
  18: } 
  19:? 

?

以下引用這個博客的,堆和棧的區別:

http://www.cnblogs.com/hfww/archive/2011/06/04/2223366.html

二、堆和棧的理論知識

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申請大小的限制

棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在 WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數),如果申請的空間超過棧的剩余空間時,將提示overflow。因 此,能從棧獲得的空間較小。

堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由于系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。

2.4申請效率的比較:

棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行。堆則是C函數庫提供的,它的機制很復雜,例如為了分配一塊內存,庫函數會按照一定的算法(具體的算法可以參考數據結構/操作系統)在堆內存中搜索可用的足夠大的空間,如果沒有足夠大的空間(可能是由于內存碎片太多),就有需要操作系統來重新整理內存空間,這樣就有機會分到足夠大小的內存,然后返回。顯然,堆的效率比棧要低得多。

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

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

另外,在WINDOWS下,最好的方式是用VirtualAlloc分配內存,他不是在堆,也不是在棧是直接在進程的地址空間中保留一快內存,雖然用起來最不方便。但是速度快,也最靈活。

?

另外...VS下更改棧大小的方法,

http://www.cnblogs.com/sosi/archive/2011/03/27/1997180.html

?

轉載于:https://www.cnblogs.com/jamesnt/p/3747216.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375858.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375858.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375858.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

讓 keil MDK 支持C99

打開options fot target-> C/C 在 Misc Controls 中添加 --c99. 轉載于:https://www.cnblogs.com/svchao/p/4585034.html

html從日期格式中獲取年,js轉換日期格式(Js獲取年月日及時間轉換)

1、獲取年、月、日和將時間戳轉換成日期格式// 簡單的一句代碼var date new Date(時間戳); //獲取一個時間對象/**1. 下面是獲取時間日期的方法,需要什么樣的格式自己拼接起來就好了2. 更多好用的方法可以在這查到 -> http://www.w3school.com.cn/jsref/jsref_o…

月半小夜曲

轉載于:https://www.cnblogs.com/yesihoang/p/4588319.html

操作系統上機作業-- 使用信號量解決生產者、計算者、消費者問題(多線程)

pc2.c: 使用信號量解決生產者、計算者、消費者問題 ? 功能和前面的實驗相同,使用信號量解決 實現思路: 生產者、計算者、消費者三者之間的關系和上一個編程任務一樣,不一樣的是,將互斥量、條件變量封裝起來作為信號量,處理方…

Singleton 單件

模式分類 從目的來看: -創建型(Creational)模式:負責對象創建 -結構型(Structural)模式:處理類與對象間的組合 -行為型(Behavioral)模式:類與對象交互中的職責…

引入struts html標簽,【學習】Struts標簽之html標簽

html:multiboxhtml:multibox標簽生成多個checkbox。當您要使用大量的checkbox時使用這個標簽非常方便,可以使您避免在ActionForm中聲明大量的boolean類型的變量,帶之以一個數組就行了。注意:為了正確的處理沒有選中的checkbox您必須在reset()中設置數組的…

10個利用Eclipse調試Java的常見技巧

http://www.open-open.com/news/view/1ad9099 閱讀目錄 1. Conditional Breakpoint2. Exception Breakpoint3. Watch Point4. Evaluation (Display or Inspect or Watch)5. Change Variable Values6. Stop in Main7. Environment Variables8. Drop to Frame9. Step Filter10. S…

操作系統上機作業--創建N個線程(多線程)

ring.c: 創建N個線程,它們構成一個環 ? 創建N個線程:T1、T2、T3、… TN ? T1向T2發送整數1 ? T2收到后將整數加1 ? T2向T3發送整數2 ? T3收到后將整數加1 ? T3向T4發送整數3 ? … ? TN收到后將整數加1 ? TN向T1發送整數N 實…

管理者不應該做的事

1.責備讓每個人明白出錯的時候要承擔責任,而不是責任他,出問題要幫他認識問題,并且給他提供解決辦法,先了解來龍去脈,看看是哪里出了問題,是否能避免 2.印象沒有人會因為你的服裝、你的車、你的財產、你的頭…

臺式計算機網線,臺式電腦如何連接寬帶_臺式電腦如何連接網線

2017-03-11 21:36:28電腦直接撥號上網(有寬帶賬號和密碼)或者自動獲取IP(有帳號沒密碼)上方式設置見圖2016-12-10 13:29:30右擊網上鄰居,點屬性,創建一個新的連接,按照下一步下一步的步驟就可以了,然后成功之后輸入你的寬帶號碼和…

棧的應用--漢諾塔

#include<stdio.h>void move(char x,int n,char y){printf("%d號盤 %c柱 ---> %c柱\n",n,x,y); }void hanoi(int n,char x,char y,char z){if(n1){move(x,1,z);}else{hanoi(n-1,x,z,y);move(x,n,z);hanoi(n-1,y,x,z);} }int main(){int n;char xX;char yY;c…

Linux split命令實例

曾經是否想要把一個大文件分割成多個小文件&#xff1f;比如一個5gb日志文件&#xff0c;我們需要把它分成多個小文件&#xff0c;這樣我們才有可能使用普通的文本編輯器讀取它。有時我們需要傳輸20gb的大文件到另一臺服務器&#xff0c;這就需要我們把它分割成多個文件&#x…

PIC18F452之1602自定義字符

源&#xff1a;PIC18F452之1602自定義字符轉載于:https://www.cnblogs.com/LittleTiger/p/4595823.html

美國計算機工程專業,美國計算機工程專業哪些學校比較好

這里有一份相對比較專業點的排名表。希望能給你當一個參考。個人建議,選擇學校還是要根據自己的實際需要,以及個人情況來決定。不一定,排名最高的學校就是好的。要多多考慮一下自己的情況。如果真的需要推薦,建議樓主寫出自己的情況,以及內心的想法,當然還要包括財力。2008美國…

NewCode----求數列的和

題目描述 數列的第一項為n&#xff0c;以后各項為前一項的平方根&#xff0c;求數列的前m項的和。 輸入描述: 輸入數據有多組&#xff0c;每組占一行&#xff0c;由兩個整數n&#xff08;n < 10000&#xff09;和m(m < 1000)組成&#xff0c;n和m的含義如前所述。 輸…

Hadoop源碼分析7: IPC流程(1) 主要類

1.服務器端主要類 public abstractclass Server { public static final ByteBuffer HEADER ByteBuffer.wrap("hrpc".getBytes()); public static final byte CURRENT_VERSION 4; private static finalThreadLocal&#xff1c;Server&#xff1e; SERVER new ThreadLo…

html5 服務器手機編程,html5實現服務器發送事件

頁面DocumentStatus:Server Datajs代碼創建一個新的 EventSource 對象&#xff0c;然后規定發送更新的頁面的 URL(本例中是 "demo_sse.php")每接收到一次更新&#xff0c;就會發生 onmessage 事件當 onmessage 事件發生時&#xff0c;把已接收的數據推入 id 為 "…

【動態規劃】【多重背包】[HDU 1291]悼念512汶川大地震遇難同胞――珍惜現在,感恩生活...

這道題目是一個多重背包的題目&#xff0c;多重背包實際上就是把整個物品的件數拆分成a0?20a1?21a2?22...an?2n且a0或1這樣每一次最優解實際上就是在之前的基礎上進行的最優解的累加&#xff0c;但是發現如果物品數量不是恰好是某幾個數之和&#xff0c;那么就會出現有幾個…

輸出字符串的比特串

48是0的ASCII碼&#xff0c;49是1的ASCII碼&#xff0c;char型占一個字節&#xff0c;四個比特。 #include<iostream> #include<string.h> using namespace std; string Str2Bin (char* str){int change,k0,mask8;char bit;char stack[100]{0};for (short i 0; i…

法律專業計算機基礎試卷答案,大學計算機基礎試題及答案

以下是小編整理的關于大學計算機基礎試題及答案&#xff0c;希望對你有幫助。一、單選題1、完整的計算機系統由(C)組成。A、運算器、控制器、存儲器、輸入設備和輸出設備B、主機和外部設備C、硬件系統和軟件系統D、主機箱、顯示器、鍵盤、鼠標、打印機2、以下軟件中&#xff0c…