當前位置:首頁 » 存儲配置 » c自由存儲區

c自由存儲區

發布時間: 2025-07-23 13:43:29

A. C或C++程序編譯時內存分為幾個存儲

在C++中,內存分成5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區
1.棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變數的存儲區。裡面的變數通常是局部變數、函數參數等。
2.堆,就是那些由new分配的內存塊,他們的釋放編譯器不去管,由我們的應用程序去控制,一般一個new就要對應一個delete。如果程序員沒有釋放掉,那麼在程序結束後,操作系統會自動回收。
3.自由存儲區,就是那些由malloc等分配的內存塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。
4.全局/靜態存儲區,全局變數和靜態變數被分配到同一塊內存中,在以前的c語言中,全局變數又分為初始化的和未初始化的,在C++裡面沒有這個區分了,他們共同佔用同一塊內存區。
5.常量存儲區,這是一塊比較特殊的存儲區,他們裡面存放的是常量,不允許修改(當然,你要通過非正當手段也可以修改)

B. C++面試題匯總

某個文件中定義的靜態全局變數(或稱靜態局部變數)作用域是------本文件內

①:默認繼承許可權:

class的繼承按照private繼承處理,struct的繼承按照public繼承處理

②:成員的默認訪問許可權

class的成員默認是private許可權, struct默認是public許可權


註:C++有內置的宏__cplusplus -------有個習慣帶「__」表示內部變數,只供內部使用;不帶雙下劃線的,表示外部介面的變數(標識符)


C++函數的三種傳遞方式為:值傳遞。指針傳遞 和 引用傳遞

註:值傳遞和指針傳遞,本質上就是指針傳遞。

在A類中fun1是虛函數;B類中fun2是虛函數。

①:機制上:c是面向過程的(c也可以是面向對象發的程序); C++是面向對象,提供了類。C++的面向對象的程序比c容易。

②:使用方向:c適合代碼體積小的,效率高的場合,如嵌入式;C++更適合上層的,復雜的;Linux核心大部分是c寫的,因為他是系統軟體,效率要求極高

③:C++是c的超集;

④:C語言是結構化編程語言,C++是面向對象編程語言。

⑤:C++側重於對象而不是過程,側重於類的設計而不是邏輯設計。


C中struct主要提供的是自定義類型,和構造一種新的類型出來;

一致的地方:

不一致的地方:

C語言: 無Protection行為; 不能定義函數,但可以有函數指針;

C++: 有Procetion行為,默認是private; 可以定義函數。

註: 就是訪問許可權,struct對於外部是完全訪問的,C++是有訪問 許可權 設置的;



正確, sizeof 是編譯時運算符,編譯時就確定了 可以看成是和及其有關的常量

註:定義數組的時候,數組的長度必須是一個確定的常量;



形參:是在定義函數時指定的參數,在未調用時他們並不佔用內存中的存儲單元。只有在調用的時候才會被分配內存,調用結束後,形參所佔用的內存單元會被釋放

實參:即你調用函數時傳遞的參數;



重載: 同一個名字空間--- -函數名相同,參數列表不同 ; 注釋:理解成一個類裡面的多個同名函數

重寫/覆蓋: 不同名字空間-----用於繼承,子類重新定義父類中 函數名相同,參數列表也相同 虛函數 的方法

重定義/隱藏:重定義(隱藏)是指派生類的函數屏蔽了與其同名的基類函數,規則如下:

a 如果派生類的函數和基類的 函數同名,但是參數不同 ,此時,不管有無virtual,基類的函數被隱藏。

b 如果派生類的函數與基類 的函數同名,並且參數也相同 ,但是基類函數沒有vitual關鍵字,此時,基類的函數被隱藏。


①: 隱藏 實現 細節 ,使得代碼能夠模塊化;擴展代碼模塊, 實現代碼重寫

②: 介面重用 :為了使用多個派生類中某個派生類的屬性正確調用


用sizeof的方法:

定義一個指針P,列印出sizeof(P),如果結果是4,怎麼標識改操作系統是32位,如果列印結果是2,則標識是16位、。


虛函數 ,是在 編譯 期就建立了。各個虛函數被組織成一個虛函數的入口地址的數組(簡而言之,就是組成了一個存放虛函數地址的數組)

虛函數表 指針 是在 運行 時建立的,也就是構造函數被調用時進行初始化的。


封裝,繼承,多態 是什麼?怎那麼用?為什麼使用它?

封裝:將客觀事物抽象成類,每個類對自身的 數據 方法 實行 protection ; 注釋 : 保護內部成員

繼承:廣義的繼承有三種實現形式:

實現繼承:指使用基類的屬性和方法,而無需額外編碼的能力;

可視繼承:子窗體使用父窗體的外觀和實現代碼

介面繼承:僅使用屬性和方法,實現之後到子類實現

前兩種和後一種構成了功能復用的兩種方法

多態: 主要是為了抽象


只要是函數都會做類型檢查。

這是內聯函數跟宏觀比的優勢。


①:靜態存儲區域分配; 內存在編譯的時候就已經分配好了,這塊內存在程序的整個運行期間都存在。例如全局變數。

②:在展區創建;在執行函數時,函數內局部變數的存儲單元都可以在棧上創建,函數執行結束時,自動被釋放。效率高,但是內存容量有限。

③:從堆上分配:或者叫:動態內存分配。程序員自己負責在何時用free或delete釋放內存。


C語言中用帶參數的宏定義,C++中用inline



生命周期不同 空間 周期

局部變數 函數調用時創建,結束時銷毀。static除外

局部變數不具有外部鏈接,全局變數

全局變數 靜態數據區

局部變數: 放在棧區


malloc、free是C++/C語言標准庫,new、delete是C++運算符。

注意:new、delete不是庫函數;

malloc/free 無法 滿足 對象在創建的時候要自動 執行 構造函 數,對象消亡之前要自動執行 析構函數 。他們是庫函數,而不是運算符,不在編譯器的控制許可權內,。

new、delete 能完成內存的分配和釋放,已經初始化和清理工作。


判斷指針是否為空,如果空,則列印錯誤log,並且return,終止本函數。


不是,兩個不同類型的指針可以強制轉換。


動態申請;

知道運行時才知道一個對象需要多少存儲空間,不需要知道對象的生存周期有多長。



Debug調試版本,它包含調試信息,比如assert的適用,並且不作任何優化,便於程序員調試程序。

Release稱為發布版本,他往往時進行了各種優化,


析構函數時特殊的類成員函數,沒有返回類型,沒有參數,不能隨意調用,也沒有重載,只有在類對象的生命周期結束時,有系統自己調用。優勢方內存空間的作用。

虛函數是C++多態的一種表現,使用虛函數,我們可以靈活的進行動態綁定,當然是以一定的開銷為代價

(這里虛函數的適用還是不太懂,需要進一步學習,比如怎麼調用子類的一切啊)



導致文件描述符結構中指針指向的內存背重復釋放,進而導致一些不可預期的異常。


比如全局變數的初始化,就不是有main函數引起的。例如:


全局對象的構造函數,會在main函數之前執行。


多態,純虛函數,抽象類

內聯函數


虛函數的特點:如果希望派生類能夠重新定義基類的方法,則在基類中將該方法定義為虛方法,這樣可以啟用動態聯編。

內聯函數的特點:使用內聯函數的目的屎我了提高函數的運行俠侶。內聯函數的代碼不能過長,因為內聯函數省去調用函數的時間是以代碼膨脹為代價的。內聯函數不能包含循環語句。因為執行循環語句要比調用函數的開銷大。



函數模板的實例化是由編譯程序在處理函數嗲用時自動完成的,

類模板的實例化必須由程序員在程序中顯示的指定


函數名和參數列表


不能被重載的運算符:

①:不能改變C++內部數據類型(如int float 等)的運算符

②:不能重載「.」,因為.在類中對任何成員都有意義,已經成為標准用法

③:不能重載目前C++運算符集合中沒有的符號,如:@, 等。願意:一是難以理解,二是無法確定優先順序

④:對已經存在的運算符重載不能改變優先順序規則,否則將引起混亂。


有可能是派生類無法調用析構函數


模板可以說比較古老了,但是當前的泛型編程實質上就是模板編程。他體現了一種通用和泛化的思想。


STL有7中容器:

vector(零食進行存儲數據的訪問),list(經常進行數據的增刪改查),deque(隊列結構),map,multimap,set(構造棧形的數據使用),multiset.

容器是一種特定用途的類;


淺拷貝 知識拷貝了指針沒有拷貝資源

深拷貝進行了資源的拷貝




三元表達式「?:」問好後面的兩個操作數必須為同一個類型。否則會出問題。




總的來說,堆是C語言和操作系統的術語,是操作系統維護的一塊動態分配內存;自由存儲是C++中通過 new與delete動態分配和釋放對象的抽象概念。 他們並不是完全一樣。

從技術上來說,堆(heap)是C語言和操作系統的術語。堆是操作系統所維護的一塊特殊內存,它提供了動態分配的功能,當運行程序調用malloc()時就會從中分配,稍後調用free可把內存交還。而自由存儲是C++中通過new和delete動態分配和釋放對象的抽象概念,通過new來申請的內存區域可稱為自由存儲區。基本上,所有的C++編譯器默認使用堆來實現自由存儲,也即是預設的全局運算符new和delete也許會按照malloc和free的方式來被實現,這時藉由new運算符分配的對象,說它在堆上也對,說它在自由存儲區上也正確。

程序編譯的過程中就是將用戶的文本形式的源代碼(c/c++)轉化成計算機可以直接執行的機器代碼的過程。主要經過四個過程:預處理、編譯、匯編和鏈接。具體示例如下。

一個hello.c的c語言程序如下。

其編譯過程如下:

C. C語言的堆棧和單片機里的堆棧的聯系和區別

堆棧在C語言中的定義(單片機的中堆棧相當於棧)

在計機領域,堆棧是一個不容忽視的概念,我們編寫的C語言程序基本上都要用到。但對於很多的初學著來說,堆棧是一個很模糊的概念。堆棧:一種數據結構、一個在程序運行時用於存放的地方,這可能是很多初學者的認識,因為我曾經就是這么想的和匯編語言中的堆棧一詞混為一談。我身邊的一些編程的朋友以及在網上看帖遇到的朋友中有好多也說不清堆棧,所以我想有必要給大家分享一下我對堆棧的看法,有說的不對的地方請朋友們不吝賜教,這對於大家學習會有很大幫助。

首先了解下計算機C語言中各個變數的存放區域:

代碼區(CODE):
存放函數代碼;
靜態數據區(DATA):
存放全局變理/靜態變數;

堆區(HEAP): 是自由存儲區,存放動態數據,像new,malloc()申請的空間就是堆區的;

棧區(STACK): 存放臨時/局部變數。

數據結構的棧和堆

首先在數據結構上要知道堆棧,盡管我們這么稱呼它,但實際上堆棧是兩種數御渣高據結構:堆和棧。

堆和棧都是一種數據項按序排列的數據結構。

棧就像裝數據的桶或箱子

我們先從大家比較熟悉的棧說起吧,它是一種具有後進先出性質的數據結構,也就是說後存放的先取,先存放的後取。這就如同我們要取出放在箱子裡面底下的東西(放入的比較早的物體),我們首先要移開壓在它上面的物體(放入的比較晚的物體)。

堆像一棵倒過來的樹

而堆就不同了,堆是一種經過排序的樹形數據結構,每個結點都有一個值。通常我們所說的堆的數據結構,是指二叉堆。堆的特點是根結點的值最小(或最大),且根結點的兩個子樹也是一個堆。由於堆的這個特性,常用來實現優先隊列,堆的存取是隨意,這就如同我們在圖書館的書架上取書,雖然書的擺放是有順序的,但是我們想取任意一本時不必像棧一樣,先取出前面所有的書,書架這種機制不同於箱子,我們可以直接取出我們想要的書。

內存分配中的棧和堆

然而我要說的重點並不在這,我要說的堆和棧並不是數據結構的堆和棧,之所以要說數據結構的堆和棧是為了和後面我要說的堆區和棧區區別開來,請大家一定要注意。

下面就說說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); 堆
}

0.申請方式和回收方式不同

不知道你是否有點明白了,堆和棧的第一個區別就是申請方式不同:棧(英文名稱是stack)是系統自動分配空間的,例如我們定義一個 char a;系統會自動在棧上為其開辟空間。而堆(英文名稱是heap)則是程序員根據需要自己申請的空間,例如malloc(10);開辟十個位元組的空間。由於棧上的空間是自動分配自動回收的,所以棧上的數據的生存周期只是在函數的運行過程中,運行後就釋放掉,不可以再訪問。而堆上的數據只要程序員不釋放空間,就一直可以訪問到,不過缺點是一旦忘記釋放會造成內存泄露。還有其他的一些區別我認為網上的朋友總結的不錯這里轉述一下:

1.申請後系統的響應

棧:只要棧的剩餘空間大於所申請空間,系統將為程序提供內存,否則將報異常提示棧溢出。

堆:首先應該知道操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,會遍歷該鏈表,尋找第一個空間大於所申請空間的堆。

結點,然後將該結點從空閑結點鏈表中刪除,並將該結點的空間分配給程序,另外,對於大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣,代碼中的
delete語句才能正確的釋放本內存空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閑鏈表中。

也就是說堆會在申請後還要做一些後續的工作這就會引出申請效率的問題。

2.申請效率的比較

根據第0點和第1點可知。

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

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

3.申請大小的限制

棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在
WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。

4.堆和棧中的存儲內容

由於棧的大小有限,所以用子函數還是有物理意義的,而不僅僅是邏輯意義。

棧:在函數調用時,第一個進棧的是主函數中函數調用後的下一條指令(函數調用語句的下一條可執行語句)的地址,然後是函數的各個參數,在大多數的C編譯器中,參數是由右往左入棧的,然後是函數中的局部變數。注意靜態變數是不入棧的。

當本次函數調用結束後,局部變數先出棧,然後是參數,最後棧頂指針指向最開始存的地址,也就是主函數中的下一條指令,程序由該點繼續運行。
堆:一般是在堆的頭部用一個位元組存放堆的大小。堆中的具體內容有程序員安排。

關於存儲內容還可以參考這道題。這道題還涉及到局部變數的存活期。

5.存取效率的比較

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

關於堆和棧區別的比喻

堆和棧的區別可以引用一位前輩的比喻來看出:

使用棧就象我們去飯館里吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等准備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。

使用堆就象是自己動手做喜歡吃的菜餚,比較麻煩,但是比較符合自己的口味,而且自由度大。比喻很形象,說的很通俗易懂,不知道你是否有點收獲

熱點內容
安卓q幣如何充王者榮耀 發布:2025-07-23 20:58:52 瀏覽:689
線程編程題 發布:2025-07-23 20:58:47 瀏覽:599
蘋果如何快傳照片給安卓 發布:2025-07-23 20:46:09 瀏覽:555
qq賬號哪裡可以清除緩存 發布:2025-07-23 20:43:55 瀏覽:136
我的世界精靈寶可夢伺服器打開 發布:2025-07-23 20:43:48 瀏覽:803
SQL撐爆 發布:2025-07-23 20:30:25 瀏覽:287
搭建伺服器的模式有哪幾種 發布:2025-07-23 20:21:48 瀏覽:729
c語言編寫的菱形圖案 發布:2025-07-23 20:05:02 瀏覽:399
php生成編號 發布:2025-07-23 19:56:47 瀏覽:704
伺服器密室殺手老是當偵探怎麼辦 發布:2025-07-23 19:43:57 瀏覽:539