《STL源码剖析》问题总结

article/2025/9/14 0:34:45

个人笔记,持续更新,如果有遇到相同的疑问希望可以帮助大家。

Allocator
P45
问题1:

T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));

调用系统全局operator new函数来申请一个内存空间,传入参数为size_t类型,使用了一个强制类型转换,函数返回void类型指针,再使用强制类型转换为T,赋给tmp指针,指向申请的内存空间。
https://www.cnblogs.com/raichen/p/5808766.html
C++ new操作包括两个步骤:(1)调用::operator new 配置内存;(2)调用构造函数构造对象内容。

问题2:

template <class T1, class T2>
inline void _construct(T1* p, const T2& value){new(p) T1(value);
}

placement new操作,需要包含new.h头文件,就是在定向new一个对象。使用new在p指针指向的内存空间生成一个T1类型的对象,利用T2类型的对象value来进行初始化。
https://blog.csdn.net/u014209688/article/details/90047713

P51
问题1:

template <class ForwardIterator, class T>
inline void __destroy(ForwardIterator first, ForwardIterator last, T*){typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;__destroy_aux(first, last, trivial_destructor());
}

traits编程技巧,对于默认数据类型(int, long, double, float…),其析构由编译器自行完成,因此对其进行显式析构是无意义的(trivial),即判断其存在trivial destructor, 所以对其不作任何处理,否则显式析构。
https://blog.csdn.net/pililipalalar/article/details/53446918
SGI ALLOC示意
在2.3节内存基本处理工具部分也采用了同样的编程技巧。

P57
问题1:

static void (* set_malloc_handler(void (*f)()))()
{void (* old)() = __malloc_alloc_oom_handler;__malloc_alloc_oom_handler = f;return(old);
}

函数名搞得十分复杂,对于我这种初学者十分不友好,查阅了相关资料发现应该从里往外读。

void (*f)()

指一个void(*)()类型的函数指针f

set_malloc_handler(void (*f)())

set_malloc_handler接受一个void(*)类型的函数指针参数。

static void (* set_malloc_handler(void (*f)()))()

定义了一个函数set_malloc_handler,它接受一个void ()()类型的参数f,返回类型为void ()()。
这里需要区分函数指针和返回类型为指针的函数:

// 函数指针
int (*p)(int, int){}// 函数的返回类型为指针
int* p(int, int){}

https://www.cnblogs.com/Chierush/p/3745520.html
https://blog.csdn.net/charles1e/article/details/51620673

知识点:
函数指针

P58
问题1:

/**
*  初始值为0,由用户指定内存不足时的处理函数
*/
template<int inst>
void (*_malloc_alloc_template<int inst>::_malloc_alloc_oom_handler)() = 0;template<int inst>
void *_malloc_alloc_template<int inst>::oom_malloc(size_t n){void (*my_malloc_handler)();void *result;for(;;){my_malloc_handler = _malloc_alloc_oom_handler;if(0 == my_malloc_handler){_THROW_BAD_ALLOC;}//调用处理函数,企图释放其他内存(*my_malloc_handler)();//再次尝试配置内存result = malloc(n);if(result){return result;}}
}

如果不太明白函数指针,可以理解一下这个地方的代码含义:__malloc_alloc_oom_handler函数由客端自己设定,如果默认则为0。在函数体中,首先将__malloc_alloc_oom_handler函数赋给函数指针my_malloc_handler(代表后者可以直接调用前面的函数),如果其为0,则说明客端没有设定处理函数,直接抛出异常,否则调用处理函数,再重新尝试配置内存,直至成功。

P60
知识点:
结构体和联合的内存对齐

问题1:

union obj{union obj* free_list_link;char client_data[1];
};

结合union的特点,这里可以看做一物二用。看第一字段,obj视为一个指针,指向同类型的下一个obj指针,看第二字段,obj视为一个指针,指向实际区块。

P61
知识点:
枚举

P62
知识点:
volatile关键字:随时可能更改的变量

P68
知识点:
内存池(Memory Pool):

template <bool __threads, int __inst>
char*
__default_alloc_template<__threads,__inst>::_S_chunk_alloc(size_t __size,int&__nobjs)
{char* __result;size_t __total_bytes = __size * __nobjs;size_t __bytes_left = _S_end_free - _S_start_free; // 内存池剩余空间if (__bytes_left >= __total_bytes) { // 内存池剩余空间完全满足需求__result= _S_start_free;_S_start_free+= __total_bytes;return(__result);} else if (__bytes_left >= __size) { // 内存池剩余空间不能完全满足需求,但足够供应一个(含)以上的区块__nobjs= (int)(__bytes_left/__size);__total_bytes= __size * __nobjs;__result= _S_start_free;_S_start_free+= __total_bytes;return(__result);} else { // 内存池剩余空间连一个区块的大小都无法提供size_t __bytes_to_get =2 *__total_bytes + _S_round_up(_S_heap_size >> 4);//Try to make use of the left-over piece.//把内存池当前剩下的一些小残余零头利用一下。if (__bytes_left > 0) {_Obj*__STL_VOLATILE* __my_free_list =_S_free_list+ _S_freelist_index(__bytes_left); ((_Obj*)_S_start_free)-> _M_free_list_link = *__my_free_list;*__my_free_list= (_Obj*)_S_start_free;}_S_start_free= (char*)malloc(__bytes_to_get);if (0 == _S_start_free) {size_t __i;_Obj*__STL_VOLATILE* __my_free_list;_Obj*__p;//Try to make do with what we have.  That can't//hurt.  We do not try smaller requests, since that tends//to result in disaster on multi-process machines.for (__i = __size;__i<= (size_t) _MAX_BYTES;__i+= (size_t) _ALIGN) {__my_free_list= _S_free_list + _S_freelist_index(__i);__p= *__my_free_list;if (0 != __p) {*__my_free_list= __p -> _M_free_list_link;_S_start_free= (char*)__p;_S_end_free= _S_start_free + __i; return(_S_chunk_alloc(__size,__nobjs));//Any leftover piece will eventually make it to the//right free list.}}_S_end_free= 0;    // In case of exception._S_start_free= (char*)malloc_alloc::allocate(__bytes_to_get);//This should either throw an//exception or remedy the situation.  Thus we assume it//succeeded.}_S_heap_size+= __bytes_to_get;_S_end_free= _S_start_free + __bytes_to_get;return(_S_chunk_alloc(__size,__nobjs));}
}

chunk_alloc()函数以end_free - start_free来判断内存池的水量。如果水量充足,则直接调出20个区块;不足但能提供1个以上区块则拨出这不足的20个区块,如果1个区块都拨不出去,则利用malloc从heap中申请内存,为内存池注入活水源头以应付需求,新水量为需求量的两倍,再加上一个随配置次数增加而愈来愈大的附加量。

Iterators
P81
知识点:
explicit关键字:阻止隐式转换
智能指针

P101
traits编程技法


http://chatgpt.dhexx.cn/article/cwdW6pyd.shtml

相关文章

STL源码剖析 map

所有元素会根据元素的键值自动被排序 元素的类型是pair&#xff0c;同时拥有键值和实值&#xff1b;map不允许两个元素出现相同的键值pair 代码 template <class T1,class T2> struct pair{typedef T1 first_type;typedef T2 second_type;T1 first; //publicT2 seco…

STL源码剖析-重点知识总结

STL是C重要的组件之一&#xff0c;大学时看过《STL源码剖析》这本书&#xff0c;这几天复习了一下&#xff0c;总结出以下LZ认为比较重要的知识点&#xff0c;内容有点略多 :) 1、STL概述 STL提供六大组件&#xff0c;彼此可以组合套用&#xff1a; 容器&#xff08;Containers…

C++标准库(第二版).pdf与STL源码剖析.pdf下载

链接&#xff1a;https://pan.baidu.com/s/1KJjkz19AdFd_UHQzBwHd8A 提取码&#xff1a;2191 链接&#xff1a;https://pan.baidu.com/s/1754Oi4BdBE2sNhOndxDUYg 提取码&#xff1a;uzmy 如有侵权&#xff0c;请联系algsCG来进行删除。

STL源码分析(总结)

STL六大组件 容器&#xff08;containers&#xff09;&#xff1a;是一种class template&#xff0c;里面包含各种数据结构。算法&#xff08;algorithms&#xff09;&#xff1a;是一种function template&#xff0c;里面包含各种算法。迭代器&#xff08;iterators&#xff…

STL源码剖析总结

STL源码剖析总结——使用c标准库 前段时间学习了STL&#xff0c;今日开始复盘&#xff0c;整理下汇总&#xff0c;图片均引自侯捷STL源码剖析 GP&#xff08;Generic Programming&#xff09;泛型编程最成功的就是STL&#xff08;Standard Template Library&#xff09;,以头…

《STL源码剖析》总结

&#xfeff;&#xfeff; 转载自 &#xff1a;http://blog.csdn.net/liguohanhaha/article/details/52089914 1、STL概述 STL提供六大组件&#xff0c;彼此可以组合套用&#xff1a; 容器&#xff08;Containers&#xff09;&#xff1a;各种数据结构&#xff0c;如&#x…

STL源码剖析---红黑树原理详解上

转载请标明出处&#xff0c;原文地址&#xff1a;http://blog.csdn.net/hackbuteer1/article/details/7740956 一、红黑树概述 红黑树和我们以前学过的AVL树类似&#xff0c;都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡&#xff0c;从而获得较高的查找性能。不…

C++ STL源码剖析 笔记

写在前面 记录一下《C STL源码剖析》中的要点。 一、STL六大组件 容器&#xff08;container&#xff09;&#xff1a; 各种数据结构&#xff0c;用于存放数据&#xff1b;class template 类泛型&#xff1b;如vector, list, deque, set, map&#xff1b; 算法&#xff08;a…

STL(C++标准库,体系结构及其内核分析)(STL源码剖析)(更新完毕)

文章目录 介绍Level 0&#xff1a;使用C标准库0 STL六大部件0.1 六大部件之间的关系0.2 复杂度0.3 容器是前闭后开&#xff08;左闭右开&#xff09;区间 1 容器的结构与分类1.1 使用容器Array1.2 使用容器vector1.3 使用容器list1.4 使用容器foward_list1.5 使用容器slist1.6 …

STL源码详解

STL详解 STL介绍空间配置器一级空间配置器二级空间配置器 序列式容器vectorlistdeque 适配器stackqueueheappriority_queue 关联式容器setmultisetmapmultimap 非标准容器hash_set&#xff08;unordered_set&#xff09;hash_multiset&#xff08;unordered_multiset&#xff0…

STL源码刨析

1. STL概述 STL起源&#xff1a; 为的就是复用性的提升&#xff0c;减少人力资源的浪费&#xff0c;建立了数据结构与算法的一套标准。 STL所实现的、是依据泛型思维架设起来的一个概念结构。这个以抽象概念〔 abstract concepts&#xff09;为主体而非以实际类(classes&…

侯捷——STL源码剖析 笔记

侯捷——STL源码剖析 笔记 1.总览 1.STL六大部件之间的关系 在下图中&#xff0c;我们使用了如下&#xff1a; 1.一个容器vector 2.使用vector时&#xff0c;使用分配器分配内存 3.使用vi.begin(),vi.end()即迭代器&#xff0c;作为算法的参数 4.使用count_if算法 5.使用仿函…

【GeoServer】CentOS7.x上GeoServer的安装部署

GeoServer 是 OpenGIS Web 服务器规范的 J2EE 实现&#xff0c;利用 GeoServer 可以方便的发布地图数据&#xff0c;允许用户对特征数据进行更新、删除、插入操作&#xff0c;通过 GeoServer 可以比较容易的在用户之间迅速共享空间地理信息。 GeoServer 主要特性&#xff1a;兼…

部署GeoServer

部署GeoServer 部署方式很多总&#xff0c;这里介绍两种 安装包安装 默认已经安装了Tomcat&#xff1a; Tomcat9.0安装教程 下载war包 使用geoserver的war包在tomcat中部署&#xff0c;从官网中下载对应版本的war GeoServer官网地址 安装 解压软件 将war包复制到tomcat…

GeoServer安装部署

介绍&#xff1a; Geoserver 是一个开源的地理空间数据服务器,它可以发布和编辑地理数据。这里简单介绍 Geoserver 的部署安装和后台运行。 它的主要功能包括: 管理空间数据&#xff1a;GeoServer可以连接各种空间数据源,包括文件(SHP、CSV等)、数据库(PostGIS,Oracle,SQL Ser…

geoserver 创建只读用户

目录 一、创建只读角色 一、创建新账号&#xff0c;将新账号添加到只读角色中 三、配置权限 四、校验 一、创建只读角色 1、选择Security->Users,Groups,Roles->Roles->Add new role 2、输入名称&#xff0c;parent role 不选&#xff08;防止获取到父级角色的权限…

GeoServer学习笔记-01GeoSever运行编译

一、运行 1. 下载GeoServer GitHub仓库地址&#xff1a;https://github.com/geoserver/geoserver 2.本地代码工具打开项目 在idea里&#xff0c;文件->新建->来自现有的源代码项目&#xff0c;选择项目的pom文件加载项目。 3.idea编译环境设置 &#xff08;1&#xff09;…

java geoserver_本机搭建GeoServer

最近尝试试本机搭建GeoSrver的服务&#xff0c;分享一下搭建安装教程&#xff0c;总共分为以下几步&#xff1a; 下载Java的GDK&#xff0c;添加环境变量 GeoServer 依赖于Java的环境&#xff0c;劝告一定要下载 1.8(8)的版本&#xff0c;虽然现在已经更新到 14&#xff0c;但是…

Geoserver中跨域问题解决

场景 GeoServer简介、下载、配置启动、发布shapefile全流程(图文实践)&#xff1a; GeoServer简介、下载、配置启动、发布shapefile全流程(图文实践)_霸道流氓气质的博客-CSDN博客 上面安装Geoserver的基础下。 使用ajax请求GeoJson时提示跨域 注&#xff1a; 博客&#x…

GeoServer发布服务,中文标注乱码

1.问题&#xff1a; 发布的矢量数据源 shapefiles&#xff0c;中文标注显示乱码问题&#xff0c;如下图所示&#xff1a; 2.解决办法 编辑矢量数据源&#xff0c;DBF文件的字符集&#xff0c;改为GB2312。 显示正常&#xff1a;