C++晋升之std中vector的实现原理(标准模板动态库中矢量的实现原理)

本文探讨了在程序运行过程中动态内存管理的重要性,并详细解释了两种常见的内存扩容策略:直接复制与预留空间机制。通过对比这两种方法,阐述了预留空间机制如何减少内存复制次数并提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们实现的数据结构是为了解决在执行过程中动态的开辟空间使用(比如我们不停的输入,输入的多少我们不确定)

假设当你看到这篇文章的话,就当作是零食咀嚼,营养没有有BUG,能够直接看我博客中文章:CPU对内存的管理,进一步和一些改正的理解

原理两种:

一、笨办法

我们第一次用多少空间,开辟多少空间A

我们第二次用空间,会开辟大于第一次开辟的空间B,将A里的数据复制到B中,然后释放A。在C中写入新的数据

缺点:在于拷贝的次数太多,效率低


二、改进的办法

矢量有一个參数,里面填写预留的空间,增加我们填写的预留空间大小是B,这里是预留B的地址,并没有真正的开辟物理内存,预留的作用于假设这时候假设须要开辟空间做其它事情,开辟的空间会避开B。这样不好造成在这里的数据变成不连续

然后开辟空间写入数据A(A所占内存小于4K,),vector中的realloc提交数据后操作系统管理内存的机制会映射一个“内存页”4K的空间给你来使用(假设数据A大于4k,开两页、三页……)。这时候物理内存和内存地址相应起来了,当在B中继续开辟空间填写数据D,这时候存入D的物理内存并非真正的开辟。而是接着使用刚刚开辟的“内存页”,仅仅有当4K空间用完,才会再次分配一个页使用

当写入的数据超过B,会将之前的全部数据提交。会又一次保留一块空间C(至少大于B)。将B中的数据拷贝入C中。释放B

长处:拷贝次数大大降低。效率提高


问:数组的线性地址和物理地址是否都必须连续

解:数组的地址肯定连续的,可是连续不过线性地址,也就是虚拟地址,或者说是地址编号,物理地址能够不是连续的


每一个进程都能够使用2G的内存,每一个进程都有一张页表,这里有一个寄存器CR3,来保存自己进程的页表,切换进程的时候CR3替换掉

(PanPen120原创 如有建议 请留言)

### C++ 中 `std::vector` 容器内自定义结构体的相等性比较 在 C++ 中,当需要比较存储于 `std::vector` 的自定义结构体是否相等时,通常依赖重载运算符 `operator==` 来实现。以下是具体的方法和注意事项。 #### 1. 结构体内重载 `operator==` 为了使两个结构体能够通过标准算法(如 `std::equal`, `std::find` 或其他集合操作)进行比较,需在其内部定义并重载 `operator==` 函数[^2]。该函数应返回布尔值,表示两对象是否具有相同的逻辑状态。 以下是一个示例: ```cpp struct MyStruct { int id; std::string name; // 重载 == 运算符 bool operator==(const MyStruct& other) const { return (id == other.id && name == other.name); } }; ``` 上述代码中,`MyStruct` 类型的对象可以通过其成员变量 `id` 和 `name` 判断是否相等[^3]。 #### 2. 使用外部全局函数重载 `operator==` 如果不想修改原始结构体,则可以在命名空间范围内提供一个自由函数版本的 `operator==` 实现。这种方式适用于无法更改已有类型的场景。 ```cpp bool operator==(const MyStruct& lhs, const MyStruct& rhs) { return (lhs.id == rhs.id && lhs.name == rhs.name); } ``` 此方法同样支持后续的标准库功能调用。 #### 3. 应用于 `std::vector` 的比较 一旦实现了合适的 `operator==` 方法,就可以利用多种方式来判断整个向量的内容是否一致。例如,可以借助 `std::equal` 检查两个矢量是否包含相同顺序的数据项。 ```cpp #include <algorithm> #include <vector> // 假设已定义好 MyStruct 及对应的 operator== std::vector<MyStruct> vec1 = {{1, "Alice"}, {2, "Bob"}}; std::vector<MyStruct> vec2 = {{1, "Alice"}, {2, "Bob"}}; if (std::equal(vec1.begin(), vec1.end(), vec2.begin())) { std::cout << "Vectors are equal." << std::endl; } else { std::cout << "Vectors differ." << std::endl; } ``` 这里需要注意的是,目标范围 (`vec2`) 需要至少源范围一样大;否则可能会引发未定义行为。因此,在实际应用前最好先验证两者大小是否匹配。 另外,对于更复杂的条件筛选或者部分字段对比需求,还可以传递定制化的二元谓词给这些算法作为第三个参数[^1]。 --- ### 总结 综上所述,要在 C++ 中完成针对 `std::vector` 所保存之自定义结构体间的相等检验工作,核心在于适当地定义或扩展相应的等于判定机制——即通过覆写类内的或是独立声明的双目关系运算子达成目的。之后便可无缝衔接至 STL 提供的各种工具链当中去执行进一步的操作流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值