动态数组

本文探讨了C++ STL中的vector、Java的ArrayList以及Redis中的SDS(动态字符串)的扩容机制。C++ vector在GCC下采用2倍扩容,VS采用1.5倍,旨在减少内存碎片。Java ArrayList扩容同样为1.5倍,且非线程安全。Redis SDS在扩容时采取空间预分配策略,缩短操作则采用惰性空间释放,以提高效率。
摘要由CSDN通过智能技术生成

动态数组挺常用的,它和普通数组的最大区别也就是它的容量大小可变,而其中的重点也就是它的扩容机制。
本篇博客就主要记录记录我对几种常用的动态数组的理解,主要包括C++ stl里的vector,java中的ArrayList,redis中的SDS(动态字符串,本质上就是动态字符数组)
并且主要讨论它们的扩容机制。

C++ stl —— vector

vector就是一个动态(大小可变的)数组,使用vector的程序员不需要关注它的容量大小变化,如果有扩容需求时,程序会自动处理。

vector的扩容机制

vector 容器扩容的过程需要经历以下 3 步:

  1. 完全弃用现有的内存空间,重新申请更大的内存空间;
  2. 将旧内存空间中的数据,按原有顺序移动到新的内存空间中;
  3. 最后将旧的内存空间释放。

所以,vector 容器在进行扩容后,与其相关的指针、引用以及迭代器可能会失效。

vector 常见的扩容有两种,gcc是2倍扩容,而vs是1.5倍扩容。

为什么vs的vector是1.5倍扩容?相比于2倍扩容有什么优势?

如果是两倍扩容,那么之前使用过的内存空间都没办法再次被这个vector使用,因为之前的所有内存加起来都比新申请的内存小。

举个例子,在两倍扩容的情况下,之前分配的内存分别是1,2,4,8(它们现在都被释放了)。
而现在要申请的内存大小是16,而之前所有使用过的内存加起来也只有15,满足不了本次的要求(而且其实8这块内存还没有被释放,被释放内存大小的其实只有7,更加满足不了要求了),也就是说,之前释放过的内存在之后的扩容中不可能被使用。

而在1.5倍扩容的情况下,分配的内存情况可能就是这样的:
4,6,9,14,21,31.5,…
当要申请大小为31.5的内存时,之前使用过的4,6,9,14都已经被释放了,它们加起来的大小是4+6+9+14 = 33 >31.5,,如果它们刚好是连续的,那么就有可能重复利用之前释放过的内存。

java —— ArrayList

ArrayList 底层是基于数组来实现容量大小动态变化的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值