日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++运行时候库操作概述和整个程序运行流程

發布時間:2025/3/21 c/c++ 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++运行时候库操作概述和整个程序运行流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

、任何一個C/C++程序,它的背后都是一套龐大的代碼來進行支撐,以使得該程序能夠正常運行。這套代碼至少包括入口函數、及其依賴的函數所構成的函數集合。當然,它還應該包括各種標準函數(如字符串,數學運算等)的實。一般的程序運行過程如下:

1.操作系統創建進程后,把控制權交給程序的入口函數(gcc -e (_startEntryPoint)),這個函數往往是運行時庫的某個入口函數,glibc的入口函數是_start,msvc(vc6.0)是mainCRTStartup

2.入口函數對運行庫和程序運行環境進行初始化,包括堆、I/O、線程、全局變量構造函數(constructor)等。

3.調用MAIN函數,正式開始執行程序主體。

4.執行MAIN完畢,返回入口函數,進行清理工作,包括全局變量析構、堆銷毀、關閉I/O等,然后進行系統調用結束進程

二、啟動時庫主要功能模塊

1.啟動與退出,包括入口函數及其依賴函數

2.標準函數

3.I/O功能的封裝和實現,如提供PRINT

4.堆的封裝和實現

5.調試支持等

三、程序詳細運行過程

以下分析默認為windows靜態鏈接過程

1.程序執行前裝載器會把用戶的參數和環境變量壓入棧,接著操作系統把控制權交給mainCRTStartup入口函數。

用戶的參數:對應int main(int argc, char **argv)

環境變量:系統公用數據,系統搜索路徑等等

程序需要獲取用戶參數和環境變量均是從棧上獲取,需要理解棧幀的概念

2.初始化和OS版本相關的全局變量

3.初始化堆,每個進程都有屬于自己的堆。它是一次性從系統中申請一塊比較大的虛擬空間(實際需要時(如malloc)才會映射到物理頁),以后在進程中由庫的堆管理算法來維護這個堆。當堆不夠用時再繼續申請一塊大的虛擬空間繼續分配。可見,并非程序每次malloc都會調用系統API(API調用比較耗時,涉及到用戶態到內核態的上下文切換),效率比較高。

堆相關操作:

HeapCreate:創建一個堆,最終會調用virtualAlloc()系統API函數去創建堆。

HeapAlloc:malloc會調用該函數

HeapFree:free會調用該函數

HeapDestroy:摧毀一個堆

4.I/O初始化,繼承父進程打開文件表。可見,子進程是可以訪問父進程打開的文件。如果父進程沒有打開標準的輸入輸出,該進程會初始化標準輸入輸出。即初始化一下指針變量:stdin,stdout,stderr。他們都是FILE類型指針。在linux和windows中,打開文件對應于操作一個內核對象,其處于內核態,因此用戶態是不能直接操作該內核對象的。用戶只能操作與內核對象相關聯的FILE結構指針。對應關系是:


printf其實是調用stdout指針在屏幕上輸出 #define printf(args...) fprintf(stdout, ##args) Args...表示變長輸入參數。用以下四個宏根據棧來獲取。Va_list,Va_start,Va_arg,Va_end

5.獲取命令行參數和環境變量

6.初始化C庫的一些數據

7.全局變量構造,如各個全局類對象的構造函數調用和標記__attribute__((constructor))屬性的各個函數。它們都應該在進入main前進行調用。

需要調用運行時庫和C/C++編譯器、連接器的配合才能實現這個功能

1)編譯器編譯某個.cpp(設為main.cpp)文件時,會將所有的構造函數實現作為一個整體放到.init段,把析構函數實現放到.finit段,然后在,ctors段放置.init段的地址(該地址即是該文件的各個構造函數的總入口)。

2)運行時庫有一個庫是crtbegin.o,它的.ctors段放置的內容為-1,ctrend.o,她的.ctors段放置的內容也是-1。

3)用鏈接器進行連接:ld crtbegin.o main.o crtend.o 一定要按這種順序,否則出錯。鏈接后的.ELF文件是將以上各個文件的.init/.finit/.ctors等段分別合并。當然.data/.text段也會相應合并。

全局變量構造時即是遍歷.ctors段的內容,從-1(crtbegin.o)開始,再到-1(crtend.o)結束,中間每四個字節即是各個文件的構造入口函數指針,如果非0,即進行調用

8.注冊析構函數

為了支持C++類的析構函數,和標記__attribute__((destructor))屬性的各個函數在main之后會被調用,而且是按構造的相反順序進行調用的,同樣需要編譯器以及運行時庫的支持,原理跟構造相仿。只是為了逆序,使用了atexit注冊各個函數,注冊時在鏈表頭插入連接,main退出以后也是從鏈表頭開始獲取鏈表函數,并進行調用

9.執行函數主體

調用main函數執行,等待返回。在這里可以用到之前已經初始化的各種資源,如I/O,堆,申請釋放等等

10.調用析構函數

11.釋放堆

12.釋放其它資源

13.調用exit系統API退出進程


轉自:http://www.cnblogs.com/yueqian-scut/p/3952263.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的C++运行时候库操作概述和整个程序运行流程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。