1. <tt id="5hhch"><source id="5hhch"></source></tt>
    1. <xmp id="5hhch"></xmp>

  2. <xmp id="5hhch"><rt id="5hhch"></rt></xmp>

    <rp id="5hhch"></rp>
        <dfn id="5hhch"></dfn>

      1. C++和操作系統面試問題分類

        時間:2023-04-03 03:30:03 筆試題目 我要投稿
        • 相關推薦

        C++和操作系統面試問題分類

          inline的使用是有所限制的,inline只適合函數體內代碼簡單的函數使用,不能包含復雜的結構控制語句例如while switch,并且不能內聯函數本身不能是直接遞歸函數(自己內部還調用自己的函數)

        C++和操作系統面試問題分類

          C++多態實現機制:在C++中,對于有 virtual的類,其sizeof會比正常情況多處4個字節。既在類的最開始四個字節,放的是VTABLE表的地址(void *類型)。而在VTABLE中,所有虛函數是以指針數組的形式存放。 對于派生的類,即時沒有重載基類的虛函數,也會在其VTABLE占用一格。造成空間上的浪費。非虛基類沒有VTABLE,VTABLE是在構造的時候編譯器生成的。

          線程和進程:進程是操作系統資源分配的最小單位,線程是CPU運行的最小單位。linux中,使用的是用戶線程(對應核心線程:線程管理由內核實現),而且是1:1形式,既每一個線程,都對應內核中的一個輕量級進程,調度由內核實現,但是線程的管理(比如產生和結束),均有一個管理線程實現。管理線程在第一次調用pthread_create的時候生成。

          軟件開發流程:

          需求分析和項目計劃:可行性計劃,項目計劃,需求分析,測試計劃

          軟件設計說明書:功能設計說明書,實現設計說明書

          使用手冊

          測試報告

          項目總結

          C++繼承機制:

          n類成員的訪問控制方式

          public:類本身、派生類和其它類均可訪問;

          protected:類本身和派生類均可訪問,其它類不能訪問;

          private(默認):類本身可訪問,派生類和其它類不能訪問。

          繼承成員的訪問控制規則

          ——由父類成員的訪問控制方式和繼承訪問控制方式共同決定

          private+public(protectd,private)=>不可訪問

          pubic(protected)+public=>public(protected)

          public(protected)+protected=>protected

          public(protected)+private(默認)=>private

          C++中的模板和virtual異同? ==>?

          private繼承和public繼承區別? ==>?

          6. static有什么用途?(請至少說明兩種)

          1.限制變量的作用域

          2.設置變量的存儲域

          7. 引用與指針有什么區別?

          1) 引用必須被初始化,指針不必。

          2) 引用初始化以后不能被改變,指針可以改變所指的對象。

          3) 不存在指向空值的引用,但是存在指向空值的指針。

          8. 描述實時系統的基本特性

          在特定時間內完成特定的任務,實時性與可靠性

          9. 全局變量和局部變量在內存中是否有區別?如果有,是什么區別?

          全局變量儲存在靜態數據區,局部變量在堆棧

          10. 什么是平衡二叉樹?

          左右子樹都是平衡二叉樹 且左右子樹的深度差值的絕對值不大于1

          11. 堆棧溢出一般是由什么原因導致的?

          沒有回收垃圾資源

          12. 什么函數不能聲明為虛函數?

          constructor ==>C++中的類的構造函數聲明

          13. 冒泡排序算法的時間復雜度是什么?

          O(n^2)

          14. 寫出float x 與“零值”比較的if語句。

          if(x>0.000001&&x<-0.000001)

          16. Internet采用哪種網絡協議?該協議的主要層次結構?

          tcp/ip 應用層/傳輸層/網絡層/數據鏈路層/物理層

          17. Internet物理地址和IP地址轉換采用什么協議?

          ARP (Address Resolution Protocol)(地址解析協議)

          18.IP地址的編碼分為哪倆部分?

          IP地址由兩部分組成,網絡號和主機號。不過是要和“子網掩碼”按位與上之后才能區分哪些是網絡位哪些是主機位。

          19.用戶輸入M,N值,從1至N開始順序循環數數,每數到M輸出該數值,直至全部輸出。寫出C程序。

          循環鏈表,用取余操作做 ——>??

          20.不能做switch()的參數類型是:

          SWITH(表達式),表達式可以是整型、字符型以及枚舉類型等表達式。

          switch的參數不能為實型。

          淺談C/C++中Static的作用

          1.先來介紹它的第一條也是最重要的一條:隱藏。

          當我們同時編譯多個文件時,所有未加static前綴的全局變量和函數都具有全局可見性。為理解這句話,我舉例來說明。我們要同時編譯兩個源文件和一個Makefile,一個是a.c,另一個是main.c.下面是a.c的內容:#include

          char a = ’A’; //global variable

          void msg()

          { printf(”Hello\n”);}下面是main.c的內容:#include

          int main(void)

          { extern char a; // extern variable must be declared before use printf(”%c “, a);(void)msg();return 0;}下面是Makefile的內容:CC =gcc

          SRC := $(shell ls *.c)

          OBJS := $(patsubst %.c, %.o, $(SRC))

          TARGET := Main

          $(TARGET): $(OBJS)

          $(CC) $(LIBS) -o $@ $^

          %.o: %.c $(CC) $(CFLAGS) -c -o $@ $<

          clean:rm -f $(TARGET) *.o程序的運行結果是:A Hello你可能會問:為什么在a.c中定義的全局變量a和函數msg能在main.c中使用?前面說過,所有未加static前綴的全局變量和函數都具有全 局可見性,其它的源文件也能訪問。此例中,a是全局變量,msg是函數,并且都沒有加static前綴,因此對于另外的源文件main.c是可見的。

          如果加了static,就會對其它源文件隱藏。例如在a和msg的定義前加上static,main.c就看不到它們了。利用這一特性可以在不同的 文件中定義同名函數和同名變量,而不必擔心命名沖突。Static可以用作函數和變量的前綴,對于函數來講,static的作用僅限于隱藏,而對于變 量,static還有下面兩個作用。

          2.static的第二個作用是保持變量內容的持久。

          存儲在靜態數據區的變量會在程序剛開始運行時就完成初始化,也是唯一的一次初始化。共有兩種變量存儲在靜態存儲區:全局變量和static變量,只 不過和全局變量比起來,static可以控制變量的可見范圍,說到底static還是用來隱藏的。雖然這種用法不常見,但我還是舉一個例子。

          #include int fun(void){ static int count = 10; // 事實上此賦值語句從來沒有執行過return count——;} int count = 1;int main(void)

          { printf(”global\t\tlocal static\n”);for(; count <= 10; ++count)

          printf(”%d\t\t%d\n”, count, fun());return 0;}程序的運行結果是:global local static 1 10 2 9 3 8 4 7 5 6 6 5 7 4 8 3 9 2 10 1 3.static的第三個作用是默認初始化為0.其實全局變量也具備這一屬性,因為全局變量也存儲在靜態數據區。

          在靜態數據區,內存中所有的字節默認值都是0×00,某些時候這一特點可以減少程序員的工作量。比如初始化一個稀疏矩陣,我們可以一個一個地把所有 元素都置0,然后把不是0的幾個元素賦值。如果定義成靜態的,就省去了一開始置0的操作。再比如要把一個字符數組當字符串來用,但又覺得每次在字符數組末 尾加‘\0’太麻煩。如果把字符串定義成靜態的,就省去了這個麻煩,因為那里本來就是‘\0’。不妨做個小實驗驗證一下。

          #include int a;int main(void)

          { int i;static char str[10];printf(”integer: %d; string: (begin)%s(end)”, a, str);return 0;}程序的運行結果如下integer: 0; string: (begin)(end)

          最后對static的三條作用做一句話總結。首先static的最主要功能是隱藏,其次因為static變量存放在靜態存儲區,所以它具備持久性和默認值0.

          C++內存泄漏的發生方式

          以發生的方式來分類,內存泄漏可以分為4類:

          1. 常發性內存泄漏。發生內存泄漏的代碼會被多次執行到,每次被執行的時候都會導致一塊內存泄漏。比如例二,如果Something()函數一直返回True,那么pOldBmp指向的HBITMAP對象總是發生泄漏。

          2. 偶發性內存泄漏。發生內存泄漏的代碼只有在某些特定環境或操作過程下才會發生。比如例二,如果Something()函數只有在特定環境下才返回 True,那么pOldBmp指向的HBITMAP對象并不總是發生泄漏。常發性和偶發性是相對的。對于特定的環境,偶發性的也許就變成了常發性的。所以測試環境和測試方法對檢測內存泄漏至關重要。

          3. 一次性內存泄漏。發生內存泄漏的代碼只會被執行一次,或者由于算法上的缺陷,導致總會有一塊僅且一塊內存發生泄漏。比如,在類的構造函數中分配內存,在析構函數中卻沒有釋放該內存,但是因為這個類是一個Singleton,所以內存泄漏只會發生一次。另一個例子:

        char* g_lpszFileName = NULL;

        void SetFileName( const char* lpcszFileName )
        {
        if( g_lpszFileName ){
        free( g_lpszFileName );
        }
        g_lpszFileName = strdup( lpcszFileName );
        }

          例三

          如果程序在結束的時候沒有釋放g_lpszFileName指向的字符串,那么,即使多次調用SetFileName(),總會有一塊內存,而且僅有一塊內存發生泄漏。

          4. 隱式內存泄漏。程序在運行過程中不停的分配內存,但是直到結束的時候才釋放內存。嚴格的說這里并沒有發生內存泄漏,因為最終程序釋放了所有申請的內存。但是對于一個 服務器程序,需要運行幾天,幾周甚至幾個月,不及時釋放內存也可能導致最終耗盡系統的所有內存。所以,我們稱這類內存泄漏為隱式內存泄漏。舉一個例子:

        class Connection
        {
        public:
        Connection( SOCKET s);
        ~Connection();

        private:
        SOCKET _socket;

        };

        class ConnectionManager
        {
        public:
        ConnectionManager(){}
        ~ConnectionManager(){
        list::iterator it;
        for( it = _connlist.begin(); it != _connlist.end(); ++it ){
        delete (*it);
        }
        _connlist.clear();
        }
        void OnClientConnected( SOCKET s ){
        Connection* p = new Connection(s);
        _connlist.push_back(p);
        }
        void OnClientDisconnected( Connection* pconn ){
        _connlist.remove( pconn );
        delete pconn;
        }
        private:
        list _connlist;
        };

          例四

          假設在Client從Server端斷開后,Server并沒有呼叫OnClientDisconnected()函數,那么代表那次連接的 Connection對象就不會被及時的刪除(在Server程序退出的時候,所有Connection對象會在ConnectionManager的析構函數里被刪除)。當不斷的有連接建立、斷開時隱式內存泄漏就發生了。

          從用戶使用程序的角度來看,內存泄漏本身不會產生什么危害,作為一般的用戶,根本感覺不到內存泄漏的存在。真正有危害的是內存泄漏的堆積,這會最終消耗盡系統所有的內存。從這個角度來說,一次性內存泄漏并沒有什么危害,因為它不會堆積,而隱式內存泄漏危害性則非常大,因為較之于常發性和偶發性內存泄漏它更難被檢測到。

          c++內存泄漏檢測

          檢測內存泄漏的方法多種多樣,有使用內存泄漏檢測工具(比如BoundsChecker)檢測內存泄漏;有直接看代碼檢測代碼邏輯,看那些地方是否沒有釋放內存。一般地靜態內存泄漏通過工具與代碼檢查很容易找到泄漏點;動態的內存泄漏很難查,一般通過在代碼中加斷點跟蹤和 Run-Time內存檢測工具來查找。

          總的來說,要檢查內存泄漏分幾個步驟:

          1、首先寫代碼時要控制內存的釋放,比如new之后要delete,看析構函數是否真的執行(很多人編寫釋放內存的代碼在析構函數中處理的),如果沒有真正執行,就需要動態釋放對象;前段時間在一個項目中使用了單例模式對象,將構造函數和析構函數設置成保護類型,在運行代碼時退出時不執行到析構函數里面(具體也不知道什么原因),最后只有手動刪除對象。

          2、其次讓程序長時間運行,看任務管理器對應程序內存是不是一直向上增加;

          3、最后使用常用內存泄漏檢測工具來檢測內存泄漏點。

          文本主要描述一些內存泄漏檢測工具功能介紹與簡單使用方法。

          一、對于VS2005/VS2008編譯器自帶的內存檢測工具/函數。

          在 main() 函數開頭加上:

          #include “crtdbg.h”

          _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);

          二、用BoundsChecker之類的工具。

          BoundsChecker 是一個Run-Time錯誤檢測工具,它主要定位程序在運行時期發生的各種錯誤。BoundsChecker能檢測的錯誤包括:

          1、指針操作和內存、資源泄露錯誤,比如:

          內存泄露;

          資源泄露;

          對指針變量的錯誤操作。

          2、內存操作方面的錯誤,比如:

          內存讀、寫溢出;

          使用未初始化的內存。

          3、API函數使用錯誤

          三、linux下可以用valgrind檢測內存泄露錯誤。

          四、purify工具,這個是專門檢測內存的,包括泄露、越界、指針跑飛等都可以檢查,在VC上使用方便。

          五、用Windbg,試過查句柄泄漏的,比較方便。

          六、Visual Leak Detector

          Visual Leak Detector是一款用于Visual C++的免費的內存泄露檢測工具。相比較其它的內存泄露檢測工具,它在檢測到內存泄漏的同時,還具有如下特點:

          1、 可以得到內存泄漏點的調用堆棧,如果可以的話,還可以得到其所在文件及行號;

          2、 可以得到泄露內存的完整數據;

          3、 可以設置內存泄露報告的級別;

          4、 它是一個已經打包的lib,使用時無須編譯它的源代碼。而對于使用者自己的代碼,也只需要做很小的改動;

          5、 他的源代碼使用GNU許可發布,并有詳盡的文檔及注釋。對于想深入了解堆內存管理的讀者,是一個不錯的選擇。

          C++培訓:C/C++中堆和棧的區別

          一、預備知識—程序的內存分配

          由C/C++編譯的程序占用的內存分為以下幾個部分

          1、棧區(stack): 由編譯器自動分配釋放,存放函數的參數值,局部變量等。其操作方式類似于數據結構中的棧。

          2、堆區(heap): 一般由程序員分配釋放(malloc/free、new/delete), 若程序員不釋放,程序結束時可能由操作系統回收。注意它與數據結構中的堆是兩回事,分配方式倒是類似于鏈表。

          3、全局區(static): 全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域,程序結束后由系統釋放。

          4、文字常量區: 常量字符串就是放在這里的, 程序結束后由系統釋放。

          5、程序代碼區: 存放函數體的二進制代碼。

          Example:

          int a = 0; // 全局初始化區

          char *p1; // 全局未初始化區

          main()

          {

          int a; // 棧區

          char s[] = “abc”; // 棧區

          char *p2; // 棧區

          char *p3 = “123456″; // 123456\0在常量區,p3在棧上。

          static int c =0; // 全局(靜態)初始化區

          p1 = (char *)malloc(10);

          p2 = (char *)malloc(20); // 分配得來得10和20字節的區域就在堆區。

          strcpy(p1, “123456″); // 123456\0放在常量區,編譯器可能會將它與p3所指向的”123456″優化成一個地方。

          }

          二、堆和棧的理論知識

          2.1 申請方式

          棧: 由系統自動分配。 例如,聲明在函數中一個局部變量 int a; 系統自動在棧中為a開辟空間

          堆: 需要程序員自己申請,并指明大小,在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 申請效率的比較:

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

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

          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讀取字符,顯然慢了。

          三、 小結

          堆和棧的區別可以用如下的比喻來看出: 使用棧就象我們去飯館里吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。使用堆就象是自己動手做喜歡吃的菜肴,比較麻煩,但是比較符合自己的口味,而且自由度大。

          還有就是函數調用時會在棧上有一系列的保留現場及傳遞參數的操作。棧的空間大小有限定,VC的缺省是2M。棧不夠用的情況一般是程序中分配了大量數組和遞歸函數層次太深。有一點必須知道,當一個函數調用完返回后它會釋放該函數中所有的?臻g。棧是由編譯器自動管理的,不用你操心。堆是動態分配內存的,并且你可以分配使用很大的內存。但是用不好會產生內存泄漏。并且頻繁地malloc和free會產生內存碎片(有點類似磁盤碎片),因為C分配動態內存時是尋找匹配的內存的。而用棧則不會產生碎片。在棧上存取數據比通過指針在堆上存取數據快些。一般大家說的堆棧和棧是一樣的,就是棧(stack),而說堆時才是堆heap。棧是先入后出的,一般是由高地址向低地址生長。

          c++內存分配的五種方法

          在C++中,內存分成5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。

          棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變量的存儲區。里面的變量通常是局部變量、函數參數等。

          堆,就是那些由new分配的內存塊,他們的釋放編譯器不去管,由我們的應用程序去控制,一般一個new就要對應一個delete。如果程序員沒有釋放掉,那么在程序結束后,操作系統會自動回收。

          自由存儲區,就是那些由malloc等分配的內存塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。

          全局/靜態存儲區,全局變量和靜態變量被分配到同一塊內存中,在以前的C語言中,全局變量又分為初始化的和未初始化的,在C++里面沒有這個區分了,他們共同占用同一塊內存區。

          常量存儲區,這是一塊比較特殊的存儲區,他們里面存放的是常量,不允許修改(當然,你要通過非正當手段也可以修改,而且方法很多,在《const的思考》一文中,我給出了6種方法)

          明確區分堆與棧

          在bbs上,堆與棧的區分問題,似乎是一個永恒的話題,由此可見,初學者對此往往是混淆不清的,所以我決定拿他第一個開刀。

          首先,我們舉一個例子:

          void f() { int* p=new int[5]; }

          這條短短的一句話就包含了堆與棧,看到new,我們首先就應該想到,我們分配了一塊堆內存,那么指針p呢?他分配的是一塊棧內存,所以這句話的意思就是:在棧內存中存放了一個指向一塊堆內存的指針p。在程序會先確定在堆中分配內存的大小,然后調用operator new分配內存,然后返回這塊內存的首地址,放入棧中,他在VC6下的匯編代碼如下:

          00401028 push 14h

          0040102A call operator new (00401060)

          0040102F add esp,4

          00401032 mov dWord ptr [ebp-8],eax

          00401035 mov eax,dword ptr [ebp-8]

          00401038 mov dword ptr [ebp-4],eax

          這里,我們為了簡單并沒有釋放內存,那么該怎么去釋放呢?是delete p么?澳,錯了,應該是delete []p,這是為了告訴編譯器:我刪除的是一個數組,VC6就會根據相應的Cookie信息去進行釋放內存的工作。

          好了,我們回到我們的主題:堆和棧究竟有什么區別?

          主要的區別由以下幾點:

          1、管理方式不同;

          2、空間大小不同;

          3、能否產生碎片不同;

          4、生長方向不同;

          5、分配方式不同;

          6、分配效率不同;

          管理方式:對于棧來講,是由編譯器自動管理,無需我們手工控制;對于堆來說,釋放工作由程序員控制,容易產生memory leak。

          空間大。阂话銇碇v在32位系統下,堆內存可以達到4G的空間,從這個角度來看堆內存幾乎是沒有什么限制的。但是對于棧來講,一般是有一定的空間大小的,例如,在VC6下面,默認的?臻g大小是1M(好像是,記不清楚了)。當然,我們可以修改:

          打開工程,依次操作菜單如下:Project->Setting->Link,在Category 中選中Output,然后在Reserve中設定堆棧的最大值和commit。

          注意:reserve最小值為4Byte;commit是保留在虛擬內存的頁文件里面,它設置的較大會使棧開辟較大的值,可能增加內存的開銷和啟動時間。

          碎片問題:對于堆來講,頻繁的new/delete勢必會造成內存空間的不連續,從而造成大量的碎片,使程序效率降低。對于棧來講,則不會存在這個問題,因為棧是先進后出的隊列,他們是如此的一一對應,以至于永遠都不可能有一個內存塊從棧中間彈出,在他彈出之前,在他上面的后進的棧內容已經被彈出,詳細的可以參考數據結構,這里我們就不再一一討論了。

          生長方向:對于堆來講,生長方向是向上的,也就是向著內存地址增加的方向;對于棧來講,它的生長方向是向下的,是向著內存地址減小的方向增長。

          分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如局部變量的分配。動態分配由alloca函數進行分配,但是棧的動態分配和堆是不同的,他的動態分配是由編譯器進行釋放,無需我們手工實現。

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

          從這里我們可以看到,堆和棧相比,由于大量new/delete的使用,容易造成大量的內存碎片;由于沒有專門的系統支持,效率很低;由于可能引發用戶態和核心態的切換,內存的申請,代價變得更加昂貴。所以棧在程序中是應用最廣泛的,就算是函數的調用也利用棧去完成,函數調用過程中的參數,返回地址,EBP和局部變量都采用棧的方式存放。所以,我們推薦大家盡量用棧,而不是用堆。

          雖然棧有如此眾多的好處,但是由于和堆相比不是那么靈活,有時候分配大量的內存空間,還是用堆好一些。

          無論是堆還是棧,都要防止越界現象的發生(除非你是故意使其越界),因為越界的結果要么是程序崩潰,要么是摧毀程序的堆、棧結構,產生以想不到的結果,就算是在你的程序運行過程中,沒有發生上面的問題,你還是要小心,說不定什么時候就崩掉,那時候debug可是相當困難的:)

        【C++和操作系統面試問題分類】相關文章:

        行為面試的面試問題和答案12-14

        面試疑問和常見面試問題07-31

        經典面試問題和回答技巧09-27

        文員面試問題和答案03-17

        面試時間和地點問題11-19

        常見的面試問題和回答09-14

        DELL的英文面試題(硬件部分和操作系統)11-06

        面試問題樣例:決策和分析問題的能力07-31

        計算機一級基礎知識:操作系統的功能和分類11-07

        文藝部面試問題和回答09-22

        国产高潮无套免费视频_久久九九兔免费精品6_99精品热6080YY久久_国产91久久久久久无码

        1. <tt id="5hhch"><source id="5hhch"></source></tt>
          1. <xmp id="5hhch"></xmp>

        2. <xmp id="5hhch"><rt id="5hhch"></rt></xmp>

          <rp id="5hhch"></rp>
              <dfn id="5hhch"></dfn>