STL的vector中resize()和reserve的区别

本文主要介绍了STL的vector中resize()和reserve()两个成员函数的区别。先阐述了capacity和size的含义,接着分别分析了reserve()和resize()在不同参数值下的作用,指出二者共同点是不缩减容器容量,还提到list中没有reserve()和capacity(),但有resize()。

STL的vector中resize()和reserve的区别
resize()和reserve()这两个成员函数都是Vector的公有成员函数
在分析这两个函数区别之前先得清楚capacity和size的含义:
容量:即capacity,是指容器在自由内存中获得了多大的存储空间,不一定使用完;
大小:即size,指的是容器中实际元素的个数,表示你已经存在的元素的个数
1. reserve()
void reserve(size_type n);
reserve()中的参数n改变的是总空间(_capacity)的大小;(注意:他开辟出来的n
个空间并不代表就都是有效空间,只有size()大小的空间才是有效空间)
它的函数原型是这样的:
对于n值的大小,分两种情况:
(1)如果n大于容器现有的容量(capacity),比如你容器原来是100的容量,我现在指定n=200,那么就需要在自由内存区为整个容器重新分配一块新的更大的连续空间【因为vector是顺序容器,所以存储空间是连续的,如果之前的存储空间不够了,必须这样做】,然后将容器内所有的有效元素从旧位置全部复制到新位置,这个过程是调用拷贝构造函数,然后释放旧位置的所有存储空间,并调整容器的元素位置指示器。所以reserve的时候如果n比原来的大,结果只是让容器的冗余容量(即没有分配元素的存储区)变大,容器的实际大小,即元素个数并没有改变。
(2)如果n小于容器原来的容量,那么这个函数什么作用都没有。相当于白调用了。
2. resize()

它的函数原型是这样的:

void resize(size_type n, const T& c = T());
其中n是要保留的元素个数,代表的是当前要申请的有效元素的个数;如果是要新增元素的话,c则是新增元素的默认初始值。默认为T()(T()表示当T为什么类型时,c就是什么类型的默认值eg:T为int 则:T()为0,T为char 则:T()为‘\0’))

对于n值的大小,分三种情况:

(1)如果n大于容器当前的大小(即容器的size),则在容器的末尾插入n-size()个初始值为c的元素;如果没有指定初始值,那就元素类型的默认构造函数来初始化。

(2)如果n小于容器当前的大小,则删除末尾的size()-n个元素,这样就导致容器的大小变了,size 变小了。但是这种类型的容器在删除一个元素的时候并不会释放元素本身的内存空间【这也是为了保留这块空间以避免将来要插入新元素的时候又要进行存储空间重分配】,所以容器的容量即capacity其实是没有改变的。

(3)n等于容器当前的大小,则什么也不做。
显然,reserve和resize的共同点就是:都不缩减容器本身的容量。即对内存空间并没有影响。那么要是当你觉得容器的容量太多的时候,应该如何缩减容量呢。这时候需要用到一个利用swap函数的技巧。

list中没有reserve()和capacity(),但是有resize();

转载:https://www.cnblogs.com/dengwuxie/p/7275101.html

<think> 我们被要求解释STLresizereserve区别,并且有多个引用资料。我们需要根据这些引用资料来整理答案。 根据引用[1]: - reserve只有一个参数,即预留的空间大小(容量)。 - resize可以有两个参数:第一个是容器新的大小,第二个是新增元素的初始值(如果省略,则调用默认构造函数)。 引用[2]补充了resize的重载形式: - void resize(size_t n); // 新增元素默认初始化 - void resize(size_t n, const T& val); // 新增元素用val初始化 引用[3]详细说明: - resize(): 改变容器内元素的数量(size)。如果新的大小大于当前大小,则新增元素默认初始化为0(对于int,如果是其他类型则调用默认构造函数);如果新的大小小于当前大小,则多余的元素被销毁。 - reserve(): 改变容器的最大容量(capacity)。它不会生成元素,只是预留空间。如果参数大于当前capacity,则重新分配一块能存n个对象的空间,并将原有元素复制过去,销毁之前的内存。如果参数小于当前capacity,则什么都不做。 引用[4]详细解释了reserve的行为: - 如果n大于当前容量,则重新分配更大的连续空间,复制原有元素,释放旧空间。 - reserve不会改变容器的大小(size),只改变容量(capacity)。 引用[5]给出了测试代码,通过代码我们可以看出: - 初始:reserve(100)后,容量为100,大小仍为0(注意:reserve不改变大小)。 - resize(50)后,大小变为50,容量为100(因为50<100,所以容量不变)。 - resize(150)后,大小变为150,容量变为200(因为150>100,所以容量不够,需要扩容,通常扩容策略是倍增,但具体实现可能不同,这里从100扩容到200)。 - reserve(50)时,由于50小于当前容量200,所以什么也不做,容量不变。 - resize(50)后,大小变为50,容量仍为200(resize减少元素数量,但不改变容量)。 总结: 1. resize() 改变容器中元素的数量(size),可能会增加或减少元素。增加元素时,可以指定初始化值(若不指定则默认初始化)。减少元素时,多余元素被销毁(调用析构函数)。 2. reserve() 改变容器的容量(capacity),但不改变元素数量(size)。它只是预留空间,以便后续添加元素时避免多次重新分配。如果预留空间大于当前容量,则重新分配并复制元素;如果小于或等于当前容量,则无效果。 需要注意的是,resize()在增加元素数量时,如果当前容量不足以容纳新增元素,那么容器会自动扩容(容量增加),但扩容的大小不一定等于新增的元素数,通常按一定策略(如倍增)增加容量。 因此,区别如下: - resize() 修改 size,可能改变 capacity(当size增大且超过当前capacity时)。 - reserve() 只修改 capacity(当参数大于当前capacity时),不修改size。 我们用表格来清晰展示: | 函数 | 作用对象 | 改变大小(size) | 改变容量(capacity) | 参数含义 | 备注 | |-----------|----------|----------------|--------------------|------------------------------|---------------------------------------| | resize(n) | 元素数量 | 是 | 可能(若n>capacity) | n: 新的元素数量 | 新增元素默认初始化 | | resize(n, val) | 元素数量 | 是 | 可能(若n>capacity) | n:新大小, val:新增元素初值 | 新增元素用val初始化 | | reserve(n) | 预留空间 | 否 | 可能(若n>capacity) | n: 新的容量(最小容量) | 只会增加容量(当n>capacity时) | 注意:reserve(n)只有在n大于当前capacity时才会重新分配,分配后的capacity至少为n(可能更大,取决于实现,但标准要求至少为n)。而resize(n)在需要时会自动调整容量(通过内部调用reserve或类似机制),但主要目的是改变元素数量。 另外,减少元素数量(resize(n)中n<当前size)时,resize不会减少容器的容量(capacity),即内存不会被释放,只是销毁多余的元素。 同样,reserve(n)中n小于当前capacity时,容量也不会减少(通常容器不会自动缩减容量)。 根据引用[5]的代码,我们验证了上述结论。 因此,回答用户: STLresizereserve的主要区别在于: 1. resize改变容器中元素的个数(size),而reserve改变的是容器预留空间的容量(capacity)。 2. resize在增加元素时可能会自动增加容量(如果当前容量不足),而reserve只负责预留空间(如果预留空间不足则扩容)。 3. resize在增加元素时可以指定新增元素的初始值,若不指定则默认初始化;减少元素时,多余的元素会被销毁。 4. reserve只是预留空间,不影响容器中已有的元素。 最后,生成相关问题。 </think> ### STL中`resize`与`reserve`的区别STL容器(如`vector`)中,`resize``reserve`是两个关键的内存管理函数,主要区别在于**操作对象****行为逻辑**: #### 1. **核心区别总结** | 函数 | 操作对象 | 核心作用 | 是否修改元素 | |-----------|---------------|----------------------------------|-------------| | `reserve` | 容量(`capacity`) | 预分配内存空间(不初始化元素) | ❌ | | `resize` | 元素数量(`size`) | 调整容器中实际元素的数量(初始化) | ✔️ | #### 2. **详细行为分析** - **`reserve(size_t n)`** - **功能**:调整容器的**容量**(`capacity`),即预分配内存空间。 - **行为**: - 若 `n > capacity`:重新分配一块能容纳 `n` 个元素的内存空间,将原有元素复制到新空间,销毁旧内存[^3][^4]。 - 若 `n ≤ capacity`:**无任何操作**。 - **元素影响**:不创建或销毁元素,仅预留空间(`size`不变)[^1][^5]。 - **参数**:单参数 `n`(目标容量)。 - **示例**: ```cpp vector<int> v; v.reserve(100); // capacity=100, size=0 ``` - **`resize(size_t n, [const T& val])`** - **功能**:调整容器的**元素数量**(`size`),初始化或销毁元素。 - **行为**: - 若 `n > size`:新增 `(n - size)` 个元素: - 若提供 `val`,新元素初始化为 `val`; - 否则调用默认构造函数(如 `int` 初始化为 `0`)[^2][^3]。 - 若 `n < size`:销毁末尾 `(size - n)` 个元素。 - 若需扩容(`n > capacity`),**自动触发内存重分配**(类似 `reserve`)。 - **参数**:必须参数 `n`(目标元素数量),可选参数 `val`(新增元素初值)[^1][^2]。 - **示例**: ```cpp vector<int> v; v.resize(5); // size=5, 元素为 {0,0,0,0,0} v.resize(3); // size=3, 销毁末尾2个元素 v.resize(6, 99); // size=6, 新增3个元素,值为99 ``` #### 3. **关键差异对比** - **容量 vs. 元素数量** - `reserve` 只修改 `capacity`(不影响 `size`); - `resize` 修改 `size`(可能间接影响 `capacity`)。 - **内存操作** - `reserve` 仅管理内存空间; - `resize` 管理元素生命周期(构造/析构)。 - **参数灵活性** - `reserve` 仅需目标容量; - `resize` 可指定新增元素的初值。 #### 4. **示例验证(引用[^5])** ```cpp vector<int> a; a.reserve(100); // capacity=100, size=0 a.resize(50); // size=50, capacity=100(新增50个0) a.resize(150); // size=150, capacity=200(自动扩容,新增100个0) a.reserve(50); // 无操作(50 < 200) a.resize(50); // size=50, capacity=200(销毁100个元素) ``` **输出**: ``` 50 100 150 200 150 200 50 200 ``` #### 5. **使用场景建议** - **`reserve`**:预分配内存以避免频繁扩容(如已知数据量上限时)。 - **`resize`**:直接设置元素数量(如初始化容器或截断数据)。 --- ### 相关问题 1. 如何在`vector`中高效预分配内存以减少扩容开销? 2. `resize`函数的第二个参数在初始化自定义类对象时有什么注意事项? 3. 为什么`reserve`在请求容量小于当前容量时不进行内存释放? 4. STL容器中`size``capacity`的关系是什么? 5. 如何通过`resize`实现容器的快速清空?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值