當前位置:首頁 » 編程語言 » c語言函數調用堆棧

c語言函數調用堆棧

發布時間: 2024-03-13 01:59:20

c語言中"棧"和"堆"怎麼理解

堆(heap)和棧(stack)有什麼區別??

簡單的可以理解為:
heap:是由malloc之類函數分配的空間所在地。地址是由低向高增長的。
stack:是自動分配變數,以及函數調用的時候所使用的一些空間。地址是由高向低減少的。

一個由c/C++編譯的程序佔用的內存分為以下幾個部分
1、棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變數的值等。其操作方式類似於數據結構中的棧。
2、堆區(heap) — 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。

㈡ C語言中函數調用有幾種情況

函數調用有倆種情況
1:聲明函數,然後直接在函數體內調用函數,這樣的做法是先保存當前函數執行的地址,然後查找函數指針,找到函數聲明,再找到函數實現,創建一個函數堆棧,直接在函數堆棧裡面操作,然後將返回值傳給主函數。然後通過之前保存的地址,繼續執行之後的代碼。過程比較復雜。
2:內聯函數和動態庫調用,這倆種方法的函數調用比較奇特,他們不會創建單獨的函數堆棧,而是執行到內聯函數和動態庫調用區域,直接將這部分代碼,類似於「粘貼」到主函數中,省去了保存當前代碼執行地址,等等一系列的操作,省去了很多內存空間,增加帶代碼的執行效率。適合於保存一些使用頻率很高的小代碼。能節省很多的程序運行時間。

㈢ c語言中函數遞歸調用中的壓入堆棧是什麼意思啊

我通俗點說:棧這個東西,你可以想像成手槍的彈夾,你裝入子彈後,最後裝入的子彈一定是最先打出去的,對吧?這就是棧的先進後出原則。遞歸函數,你想想,一定是最後執行的函數最先執行完,然後執行倒數第二個...以此類推。壓入棧的意思就是現在內存給你一個彈夾,函數就是你的子彈,你把沒運行一次這個函數,就是向彈夾里裝了一個子彈,這就是壓棧。出棧就是當找到遞歸函數出口後,再倒著一個一個解決剛才一大堆的函數,就像手槍吧子彈一個一個在打出去。關於棧,建議你學學匯編,一下就明白了

㈣ C程序中如何使用堆棧

先從大家比較熟悉的棧說起,它是一種具有後進先出性質的數據結構,也就是說後存放的先取,先存放的後取。這就如同要取出放在箱子裡面底下的東西(放入的比較早的物體),首先要移開壓在它上面的物體(放入的比較晚的物體)。而堆就不同了,堆是一種經過排序的樹形數據結構,每個結點都有一個值。通常所說的堆的數據結構,是指二叉堆。堆的特點是根結點的值最小(或最大),且根結點的兩個子樹也是一個堆。由於堆的這個特性,常用來實現優先隊列,堆的存取是隨意,這就如同在圖書館的書架上取書,雖然書的擺放是有順序的,但是想取任意一本時不必像棧一樣,先取出前面所有的書,書架這種機制不同於箱子,可以直接取出想要的書。
下面就說說C語言程序內存分配中的堆和棧,這里有必要把內存分配也提一下,一般情況下程序存放在Rom或Flash中,運行時需要拷到內存中執行,內存會分別存儲不同的信息。
內存中的棧區處於相對較高的地址以地址的增長方向為上的話,棧地址是向下增長的,棧中分配局部變數空間,堆區是向上增長的用於分配程序員申請的內存空間。另外還有靜態區是分配靜態變數,全局變數空間的;只讀區是分配常量和程序代碼空間的;以及其他一些分區。來看一個網上很流行的經典例子:
main.cpp
int a = 0; 全局初始化區
char *p1; 全局未初始化區
main()
{
int b; 棧
char s[] = "abc"; 棧
char *p2; 棧
char *p3 = "123456"; 123456\0在常量區,p3在棧上。
static int c =0; 全局(靜態)初始化區
p1 = (char *)malloc(10); 堆
p2 = (char *)malloc(20); 堆
}
堆和棧的第一個區別就是申請方式不同:棧(英文名稱是stack)是系統自動分配空間的,例如定義一個 char a;系統會自動在棧上為其開辟空間。而堆(英文名稱是heap)則是程序員根據需要自己申請的空間,例如malloc(10);開辟十個位元組的空間。由於棧上的空間是自動分配自動回收的,所以棧上的數據的生存周期只是在函數的運行過程中,運行後就釋放掉,不可以再訪問。而堆上的數據只要程序員不釋放空間,就一直可以訪問到,不過缺點是一旦忘記釋放會造成內存泄露。

㈤ C語言中堆和棧的區別

(1)申請方式
stack:
由系統自動分配。例如,聲明在函數中一個局部變數 int a; 系統自動在棧中為a開辟空間
heap:
需要程序員自己申請,並指明大小,在c中malloc函數
如m1 = (char *)malloc(10);
在C++中用new運算符
如m2 = (char *)malloc(10);
注意:m1、m2本身是在棧中的。

(2)申請後系統的響應
棧:只要棧的剩餘空間大於所申請空間,系統將為程序提供內存,否則將報異常提示棧溢出。
堆: 首先應該知道操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,會遍歷該鏈表,尋找第一個空間大於所申請空間的堆結點,然後將該結點從空閑 結點鏈表中刪除,並將該結點的空間分配給程序,另外,對於大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣,代碼中的delete語句才能正確的釋放本內存空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閑鏈表中。
(3)申請大小的限制及生長方向
棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在WINDOWS下,棧的大小是2M(也可能是1M,它是一個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小 。
堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。
(4)申請效率的比較:
棧由系統自動分配,速度較快。但程序員是無法控制的。
堆是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配內存,他不是在堆,也不是在棧是直接在進程的地址空間中保留一快內存,雖然用起來最不方便。但是速度快,也最靈活。
(5)堆和棧中的存儲內容
棧:在函數調用時,第一個進棧的是主函數中後的下一條指令(函數調用語句的下一條可執行語句)的地址,然後是函數的各個參數,在大多數的C編譯器中,參數是由右往左入棧的,然後是函數中的局部變數。注意靜態變數是不入棧的。
當本次函數調用結束後,局部變數先出棧,然後是參數,最後棧頂指針指向最開始存的地址,也就是主函數中的下一條指令,程序由該點繼續運行。
堆:一般是在堆的頭部用一個位元組存放堆的大小。堆中的具體內容有程序員安排。

熱點內容
flashas編程 發布:2024-11-29 02:38:49 瀏覽:368
先編譯成什麼格式的文件 發布:2024-11-29 02:38:48 瀏覽:119
王者榮耀安卓q區哪個英雄好拿標 發布:2024-11-29 01:56:04 瀏覽:665
網易收件伺服器怎麼填寫 發布:2024-11-29 01:52:15 瀏覽:278
螢石攝像頭激活密碼是多少 發布:2024-11-29 01:51:38 瀏覽:579
iphone如何設置像安卓動態壁紙 發布:2024-11-29 01:37:50 瀏覽:474
電腦如何避過聯網查配置 發布:2024-11-29 01:25:16 瀏覽:972
期貨軟體編程 發布:2024-11-29 01:13:16 瀏覽:834
如何下載加密pdf文件 發布:2024-11-29 01:09:21 瀏覽:326
高通android開發 發布:2024-11-29 01:09:11 瀏覽:693