正确释放Vector内存

Vector内存管理技巧

关于Vector内存泄露的疑问。

博主采用 Vector存储一些数据,但是发现在执行 clear()之后内存并没有释放,于是怀疑产生了内存泄露。

随后有人回复:

“vector clear不影响 capacity ,你应该 swap一个空的 vector

开始并不知道回复者在说什么,于是在谷歌上搜索 vector swap clear发现已经有类似的问题出现了,并且给出了一些解决方案。


原来这样的问题在《Effective STL》中的条款17”已经指出了。

vectorstring大量插入数据后,即使删除了大量数据(或者全部都删除,即clear)并没有改变容器的容量(capacity),所以仍然会占用着内存。为了避免这种情况,我们应该想办法改变容器的容量使之尽可能小的符合当前数据所需(shrink to fit

Effective STL》给出的解决方案是:

vector<type> v;
//.... 这里添加许多元素给v
//.... 这里删除v中的许多元素
//vector<type>(v).swap(v);    ///这个不能删除对象
v.swap(vector<type>());    ///这个才是正确的
//此时v的容量已经尽可能的符合其当前包含的元素数量
//对于string则可能像下面这样
string(s).swap(s);

即先创建一个临时拷贝与原先的vector一致,值得注意的是,此时的拷贝其容量是尽可能小的符合所需数据的。紧接着将该拷贝与原先的vector v进行交换。好了此时,执行交换后,临时变量会被销毁,内存得到释放。此时的v即为原先的临时拷贝,而交换后的临时拷贝则为容量非常大的vector(不过已经被销毁)

为了证明这一点,我写了一个程序,如下:

#include <iostream>
#include <vector>
using namespace std;  
 
vector <string> v;
char ch;
int main ()
{
    for(int i=0; i<1000000; i++)
        v.push_back("abcdefghijklmn");
 
    cin >> ch;
    // 此时检查内存情况占用54M
    v.clear();
    cin >> ch;
    // 此时再次检查,仍然占用54M
 
    cout << "Vector 的容量为" << v.capacity() << endl;
    // 此时容量为 1048576
 
    ///vector<string>(v).swap(v);   ///错误
     v.swap( vector<string>());    //正确方法
 
    cout << "Vector 的容量为" << v.capacity() << endl;
    // 此时容量为0
    cin >> ch;
    // 检查内存,释放了 10M+即为数据内存
    return 0;
}


总结

从这个事情说明,自己对STL的了解还非常的不够平时对vector的清除都懂得采用 clear方法。

另一方面对于STL的设计思想也有些了解,在创建一个vector vector的实际容量一般会比给数据要大,这样做应该是避免过多的重新分配内存吧。

当然,上面这种方法虽然释放了内存,但是同时也增加了拷贝数据的时间消耗。不过一般需要重新调整容量的情况都是 vector本身元素较少的情况,所以时间消耗可以忽略不计。

因此建议以后大家都将调用 clear()改为 swap()吧。

注意:正确用法。之前的文章的用法是错误的,我已经修改为正确的用法了。


摘自:http://blog.jobbole.com/37700/

<think> 首先,用户正在查询有关std::vector在C++中释放内存的方法。 我需要基于系统指令和提供的引用构建一个结构化的回答。 关键系统指令: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式。 - 在中文中回复。 - 生成相关问题。 - 在引用的段落末尾自然地添加引用标识,例如[^1]。 - 回答要结构清晰,逐步解决问题。 提供的引用: - [1]:讨论了shrink_to_fit()方法及其行为,并提到通过重新创建对象来回收内存。 - [2]:展示了shrink_to_fit()的用法示例。 - [3]:讨论了动态扩展的开销。 - [4]:列出了多种内存清理方法:shrink_to_fit()、临时变量析构、赋值操作符重载、主动调用析构函数。 用户查询:“我想查找std::vector内存释放的方法 请问std::vector内存释放的方法” 这翻译为:“I want to find the method to release memory for std::vector. What is the method to release memory for std::vector?” 我的回答需要: 1. 结构清晰:逐步解释方法。 2. 使用中文。 3. 在适当的地方引用引用内容。 4. 在最后生成相关问题。 5. 确保格式正确。 大纲回答: - 介绍:简要解释std::vector内存管理。 - 方法1:使用shrink_to_fit()方法。 - 方法2:通过重新创建对象(swap技巧)。 - 方法3:其他方法如使用赋值操作符或临时对象。 - 注意事项:为什么需要手动释放内存? - 结论:建议最佳实践。 - 相关问题:生成2-3个相关问题。 在回答中整合引用: - 当提到shrink_to_fit()时,引用[1]、[2]、[4]。 - 当提到重新创建对象时,引用[1]。 - 当提到其他方法时,引用[4]。 确保LaTeX语法正确: - 由于用户查询中没有数学表达式,我可能不需要使用数学格式,但如果有机会,可以使用它。例如,如果需要讨论大小或容量,可以像这样使用$size$和$capacity$。 - 在代码块中,使用反引号进行格式化。 回答结构: 1. **介绍**:解释std::vector内存分配。 2. **主要方法**: - 使用shrink_to_fit() - 使用swap技巧 - 其他方法 3. **代码示例**:展示一些示例以使其清晰。 4. **注意事项**:讨论shrink_to_fit()不一定立即减少容量。 5. **总结**:推荐方法。 6. **相关问题**:生成相关问题。 最后,添加相关问题部分。 </think>### std::vector 内存释放方法 在 C++ 中,`std::vector` 是一种动态数组容器,它会自动管理内存分配。但当元素减少时,容器的容量(`capacity`)可能不会自动缩小,导致内存浪费。您需要手动释放多余内存。以下是主要的释放方法,基于引用内容逐步说明: #### 1. **使用 `shrink_to_fit()` 方法** - 这是 C++11 引入的官方方法,可用于请求释放未使用的内存。调用后,容器的容量($capacity$)会尝试缩小以匹配当前大小($size$),但具体行为取决于编译器实现,可能不会立即生效[^1][^2][^4]。 - **代码示例**: ```cpp std::vector<int> v = {1, 2, 3, 4, 5}; v.reserve(100); // 预分配100个元素的内存 v.pop_back(); // 减少元素,但容量可能不变 v.shrink_to_fit(); // 释放未使用的内存,使 capacity ≈ size ``` - **注意事项**:`shrink_to_fit()` 只是建议性的,编译器可能忽略此请求,因此不保证内存立即释放。在性能敏感场景中,需结合其他方法[^1][^4]。 #### 2. **通过重新创建对象释放内存(swap 技巧)** - 如果 `shrink_to_fit()` 不可靠,可以创建一个临时 `vector` 对象,并通过 `swap` 操作转移元素来释放内存。这是一种高效且跨平台兼容的方法[^1][^4]。 - **代码示例**: ```cpp std::vector<int> v = {1, 2, 3, 4, 5}; v.reserve(100); // 预分配大量内存 // 创建临时 vector 并交换,释放内存 std::vector<int>(v).swap(v); // 新 v 的 capacity 等于 size ``` - **原理**:临时对象 `std::vector<int>(v)` 复制元素时只分配所需内存,然后通过 `swap` 交换内容,原内存随临时对象析构而释放[^4]。 #### 3. **其他方法** - **赋值操作符重载**:通过赋值操作触发内存重新分配,例如 `v = std::vector<int>(v);`。这会创建一个新对象并覆盖原对象,释放多余内存[^4]。 - **利用析构函数**:在特定作用域内创建临时 `vector`,利用其析构函数自动释放内存。但需注意析构函数的可重入性[^4]。 - **注意事项**:`std::vector` 的动态扩展机制(如添加元素时重新分配内存)可能导致性能开销,但手动释放内存仅在元素减少显著时必要[^3]。 #### 为什么需要手动释放? - `std::vector` 的设计优先考虑性能:减少元素时保留容量可避免频繁重新分配,但若内存占用过大(例如容量 $capacity \gg$ 大小 $size$),应手动释放以提高资源利用率。基准测试显示,在大型容器中,swap 技巧通常比 `shrink_to_fit()` 更可靠[^1][^4]。 #### 推荐实践 - **优先选择**:对于现代 C++(C++11+),使用 `shrink_to_fit()` 简单快捷;若需保证效果,采用 swap 技巧。 - **避免场景**:频繁调用释放方法可能引发性能问题,仅在内存压力大时使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值