
引言在第一篇博客中深入浅出之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和标准库的关系标准库的代码都统一在一个命名空间stdStandard的缩写中也就是说std命名空间下的内容属于C标准库Standard Library但是并非全部属于标准模版库standard template library, stl)也就是标准模板库只是标准库的一部分。std 是 C 标准库的所有组件所在的命名空间包含以下类别STL标准模板库容器、迭代器、算法、函数对象等。非 STL 的标准库组件输入输出iostream、字符串std::string、智能指针、多线程std::thread、异常处理、类型工具type_traits等。stl的实现与编译器的关系C 标准库含 STL的源码由 编译器厂商或开源社区实现不同编译器使用不同的实现GCC使用 **libstdc**GNU 标准 C 库源码路径如 /usr/include/c/版本号Clang默认使用 libstdc但可配置为 **libc**LLVM 项目开发。MSVC使用 Microsoft STL仅限 Windows。MinGW 是gcc的windows版本。每个实现的源码结构和优化策略不同但均遵循 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文件就可以使用了为什么还有一个动态库呢/usr/lib/gcc/aarch64-linux-gnu/11/libstdc.so哪些实现需要放在.cpp中并且形成动态库呢虽然 STL 的模板代码如 vector、deque完全在头文件中实现但标准库中还有以下内容需要编译为二进制库类别示例**为什么需要二进制库**运行时支持std::exception、std::type_info需要全局唯一的 RTTI运行时类型信息和异常处理机制。动态内存管理operator new、operator delete全局内存分配器的实现需要跨编译单元共享。输入输出流std::cout、std::fstream底层文件操作和缓冲区管理需要与操作系统交互无法完全用头文件实现。多线程支持std::thread、std::mutex依赖操作系统原生线程 API如 pthread需封装为二进制接口。数学函数std::sin、std::sqrt某些数学函数需要链接到系统数学库如libm。C 标准库兼容层std::printf、std::mallocC 标准库函数如printf的实现需要预编译。标准库源码和 glibc 的区别和关系1. libstdc 和 glibc 的区别这是两个完全不同的库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 前端实现方式在大多数系统中g实际上是一个指向gcc的符号链接当以g名称调用时gcc会自动添加 C 特定的编译选项主要区别默认链接 C 标准库 (libstdc)默认使用 C 语法规则自动识别.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参数记录可执行文件对共享库的依赖。-ldl是传给ld的链接参数含义链接libdl.so库libdl.so属于glibc提供dlopen/dlsym等运行时手动加载动态库的 API。注意不是链接器是一个库。ld-linux.so如 ld-linux-x86-64.so.2归属glibcGNU C 标准库运行时动态链接器。 作用程序启动后由内核唤起读取可执行文件中记录的库依赖查询ld.so.cache自动加载.solibstdc.so、shturl.、libdl.so 等。一句话串起来 编译时ldbinutils收到-ldl标记程序依赖libdl.so程序运行时ld-linux.soglibc负责加载libdl.so。