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

来源:互联网 发布:nodejs 加载js 编辑:程序博客网 时间:2024/05/22 04:27

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

如果当你看到这篇文章的话,就当作是零食咀嚼,营养没有有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原创 如有建议 请留言)

0 0
原创粉丝点击