
引言在第一篇博客中深入淺出之STL源碼分析1_vector基本操作-CSDN博客我們將引出下面的幾個問題1.剛才我提到了我的編譯器版本是g 11.4.0而我們要講解的是STL標準模板庫那么二者之間的關系是什么以及標準庫和標準模版庫之間的關系又是什么STL安裝后我們到哪里去看源碼2.我們引入了頭文件#includevector這里的vector的內容是什么3.vectorint test_vector; 這中定義方式是干什么的作用是什么4.test_vector.push_back(22); 對于stl源碼底層到底做了什么把對應的數據插入到了哪個地址了什么時候分配的虛擬內存什么時候擴容什么時候會分配物理內存下面我們來重點來說明下問題1.stl和標準庫的關系標準庫的代碼都統(tǒng)一在一個命名空間stdStandard的縮寫中也就是說std命名空間下的內容屬于C標準庫Standard Library但是并非全部屬于標準模版庫standard template library, stl)也就是標準模板庫只是標準庫的一部分。std 是 C 標準庫的所有組件所在的命名空間包含以下類別?STL標準模板庫?容器、迭代器、算法、函數對象等。?非 STL 的標準庫組件輸入輸出iostream、字符串std::string、智能指針、多線程std::thread、異常處理、類型工具type_traits等。stl的實現與編譯器的關系C 標準庫含 STL的源碼由 ?編譯器廠商或開源社區(qū)實現不同編譯器使用不同的實現?GCC使用 ?**libstdc**?GNU 標準 C 庫源碼路徑如 /usr/include/c/版本號?Clang默認使用 libstdc但可配置為 ?**libc**?LLVM 項目開發(fā)。?MSVC使用 ?Microsoft STL僅限 Windows。MinGW 是gcc的windows版本。每個實現的源碼結構和優(yōu)化策略不同但均遵循 C 標準。stl源碼何時安裝到linux?libstdc包含 STL 頭文件隨同 GCC 工具鏈一起安裝但它獨立于 gcc 編譯器本體是配套的 C 標準庫實現。 很多人會誤以為標準庫是 gcc 程序里面的代碼其實是配套組件?安裝 GCC會同時安裝其標準庫libstdc的 ?頭文件.h/.hpp?? 和 ?預編譯二進制庫.so?。?頭文件路徑如 /usr/include/c/11/vectorGCC 11.4.0 版本。?二進制庫路徑如 /usr/lib/gcc/aarch64-linux-gnu/11/libstdc.so。一個疑問就是一般我們的stl都是頭文件的形式我們只是需要.h文件就可以使用了為什么還有一個動態(tài)庫呢/usr/lib/gcc/aarch64-linux-gnu/11/libstdc.so哪些實現需要放在.cpp中并且形成動態(tài)庫呢雖然 STL 的模板代碼如 vector、deque?完全在頭文件中實現但標準庫中還有以下內容需要編譯為二進制庫?類別??示例??**為什么需要二進制庫**??運行時支持?std::exception、std::type_info需要全局唯一的 RTTI運行時類型信息和異常處理機制。?動態(tài)內存管理?operator new、operator delete全局內存分配器的實現需要跨編譯單元共享。?輸入輸出流?std::cout、std::fstream底層文件操作和緩沖區(qū)管理需要與操作系統(tǒng)交互無法完全用頭文件實現。?多線程支持?std::thread、std::mutex依賴操作系統(tǒng)原生線程 API如 pthread需封裝為二進制接口。?數學函數?std::sin、std::sqrt某些數學函數需要鏈接到系統(tǒng)數學庫如libm。?C 標準庫兼容層?std::printf、std::mallocC 標準庫函數如printf的實現需要預編譯。標準庫源碼和 glibc 的區(qū)別和關系1. libstdc 和 glibc 的區(qū)別??這是兩個完全不同的庫????libstdc.so??這是 ??GNU C 標準庫??包含 C 標準庫的實現如std::vector,std::string,iostream等glibc??這是 ??GNU C 標準庫??包含 C 標準庫的實現如printf,malloc,strlen等??關系??你的程序通常會同時鏈接這兩個庫C 程序會使用 libstdc而 libstdc 內部可能會調用 glibc 的函數2. 下載 libstdc 源碼可以從官網下載源碼# 下載 GCC 11.x.x 完整源碼 wget https://ftp.gnu.org/gnu/gcc/gcc-11.4.0/gcc-11.4.0.tar.xz3.源碼的目錄結構gcc-11.4.0/├── libstdc-v3/│ ├── include/ # 標準頭文件如 vector, string 的定義│ ├── src/ # 實現文件│ ├── libsupc/ # 支持代碼異常處理、RTTI等│ └── testsuite/ # 測試用例├── libgcc/ # GCC 運行時庫└── gcc/ # GCC 編譯器本身這里有c編譯器gcc,也有c編譯器g4.GCC、g 和 libstdc 的關系GCC (GNU Compiler Collection)全稱??GNU Compiler Collection本質??不是一個單一程序而是一個??編譯器套件包含組件??C 編譯器 (gcc)C 編譯器 (g),還有其他程序的編譯器。一般小寫的gcc我們理解成c編譯器大寫的GCC 就是編譯器套件。g 的本質定位??GCC 套件中的 C 前端實現方式??在大多數系統(tǒng)中g實際上是一個指向gcc的符號鏈接當以g名稱調用時gcc會自動添加 C 特定的編譯選項主要區(qū)別默認鏈接 C 標準庫 (libstdc)默認使用 C 語法規(guī)則自動識別.cpp等 C 文件擴展名g,libstdc都是GCC的組成部分。5.GNU 項目都包括哪些東西GNU項目GNUs Not Unix ├─ GCCGNU Compiler Collection │ ├─ gcc/g 編譯器前端 │ ├─ libgcc 【編譯器底層運行支持庫】 │ └─ libstdc-v3C標準庫源碼 ├─ binutils │ └─ /usr/bin/ld as ar readelf ... ├─ glibcGNU C標準庫獨立項目 │ ├─ shturl. │ ├─ libdl.so-ldl │ └─ ld-linux.so └─ 其他GNU工具6.-ldl、ld、ld-linux.so關系總結ld/usr/bin/ld歸屬binutilsGNU 二進制工具集編譯期鏈接器。 作用g/gcc 編譯完成生成.o目標文件后gcc 驅動調用ld完成鏈接解析-lxxx參數記錄可執(zhí)行文件對共享庫的依賴。-ldl是傳給ld的鏈接參數含義鏈接libdl.so庫libdl.so屬于glibc提供dlopen/dlsym等運行時手動加載動態(tài)庫的 API。注意不是鏈接器是一個庫。ld-linux.so如 ld-linux-x86-64.so.2歸屬glibcGNU C 標準庫運行時動態(tài)鏈接器。 作用程序啟動后由內核喚起讀取可執(zhí)行文件中記錄的庫依賴查詢ld.so.cache自動加載.solibstdc.so、shturl.、libdl.so 等。一句話串起來 編譯時ldbinutils收到-ldl標記程序依賴libdl.so程序運行時ld-linux.soglibc負責加載libdl.so。