问题:stl中的vector容器常常造成删除假象,这对于c++程序员来说是极其讨厌的,《effective stl》大师已经将之列为第17条,使用交换技巧来修整过剩容量。
内存空洞这个名词是网上的学者给出的,我觉得用来描述这个基本现象特别容易提醒自己vector删除的这个陷阱。

首先给出一段代码:
35 void testvector()
36 {
38     vector v;
39     v.push_back(1);
40     v.push_back(2);
41     cout << "v size = " << v.size() << " v capacity = " << v.capacity()  << endl;
42     v.erase(v.begin());
43     cout << "v size = " << v.size() << " v capacity = " << v.capacity()  << endl;
44     vector(v).swap(v); // 清除v而且最小化它的容量
45     cout << "v size = " << v.size() << " v capacity = " << v.capacity()  << endl;
47 }

结果如下:
[hfx@didkey1 bin]$ ./test
v size = 2 v capacity = 2
v size = 1 v capacity = 2
v size = 1 v capacity = 1

分析:
可以清楚地看到这个问题,在第一次 v.erase(v.begin());的时候,并没有真正释放删除元素的内存,它的容量还是存着。我也简单描画下这个生活中的问题——
你拿这一个1000升的水去沙漠上旅行,开始是满的,但是,你的旅途让你的水变成了1升,而且路途中,你没有水资源让你再次灌满,那么,你一直将拖着一个1000升
容量的大水箱,载着1升水在旅行,你是不允许自己这样做的。你只有把这个水箱切了,切成10升或者1升,小点……
vector也一样,你把水喝了,并不能把水箱也缩小,要把水箱缩小的做法——
——swap()交换函数完美释放内存。
vector(v).swap(v); // 清除v而且最小化它的容量

注意:
a. erase()函数,只能删除内容,不能改变容量大小;
erase成员函数,它删除了itVect迭代器指向的元素,并且返回要被删除的itVect之后的迭代器,迭代器相当于一个智能指针。
b. clear()函数,只能清空内容,不能改变容量大小
c. vector容器删除不自动释放内存,那么它存在内存泄露???不是的,vector在析构函数的时候,对内存进行了释放。
d. 如果要想在删除内容的同时释放内存,那么你可以选择deque容器。
e. 关于vector:
vector相当于c++中的数组,数组在初始化的时候也需要给它一个数组空间大小,vector申请的时候将预留一个空间,比如10,在元素超过10的时候,vector自动将大小
扩大到两倍,并且将元素拷贝过去。

用法举例:
 vector(v).swap(v);将v的内存空洞清除
 vector().swap(v);清空vec

完美删除vector的内容与释放内存的更多相关文章

  1. (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作

    双向循环链表是基于双向链表的基础上实现的,和双向链表的操作差不多,唯一的区别就是它是个循环的链表,通过每个节点的两个指针把它们扣在一起组成一个环状.所以呢,每个节点都有前驱节点和后继节点(包括头节点和 ...

  2. vector容器删除某些元素且释放内存

    1,size和capacity size: 指目前容器中实际有多少元素,对应的resize(size_type)会在容器尾添加或删除一些元素,来调整容器中实际的内容,使容器达到指定的大小. capac ...

  3. c++ vector 释放内存

    1.释放单个指针 关于Vector中存放指针的问题,在进行清空的时候比较安全的一种做法是:    std::vector<ClassName *> ClassNameVec;    ... ...

  4. vector 利用swap 函数进行内存的释放 vector<int>().swap

    首先,vector与deque不同,其内存占用空间只会增长,不会减小.比如你首先分配了10,000个字节,然后erase掉后面9,999个,则虽然有效元素只有一个,但是内存占用仍为10,000个.所有 ...

  5. std::vector利用swap()函数进行内存的释放【转】

    首先,vector与deque不同,其内存占用空间只会增长,不会减小.比如你首先分配了10,000个字节,然后erase掉后面9,999个,则虽然有效元素只有一个,但是内存占用仍为10,000个.所有 ...

  6. vector释放内存之swap方法

    相信大家看到swap这个词都一定不会感到陌生,就是简单的元素交换.但swap在C++ STL中散发着无穷的魅力.下面将详细的说明泛型算法swap和容器中的swap成员函数的使用! 1. 泛型算法swa ...

  7. (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作

    上午写了下单向循环链表的程序,今天下午我把双向链表的程序写完了.其实双向链表和单向链表也是有很多相似的地方的,听名字可以猜到,每个节点都包含两个指针,一个指针指向上一个节点,一个指针指向下一个节点.这 ...

  8. New动态分配 Delete 释放内存

    在C++中,对于变量和对象都是编译器在编译时分配好的,对于数组初始化时,无法确定多少内存,很容意造成大开小用的情况. new  动态分配 一般格式:1. 指针变量名 =new  类型标识符; 2.指针 ...

  9. linux释放内存命令

    1.首先查看linux内存使用 #free -m 2.把内存数据同步到硬盘#sync 3.修改 /proc/sys/vm/drop_caches文件 #echo 3 > /proc/sys/vm ...

随机推荐

  1. 常见python快捷键

    http://www.cnblogs.com/toutou/p/4778818.html Ctrl+/注释(取消注释)选择的行 Shift + Enter开始新行 Ctrl + Enter智能换行 T ...

  2. 递归函数的写法(以strcpy函数为例)

    1. 递归函数模板 递归的前提是,找到一个公共子问题(或公共操作),然后将该函数构造为递归函数. retType function( ... ) { 结束条件 { [处理] 返回 } 递归条件 { [ ...

  3. [git 学习篇]版本回退

    再次修改readme.txt ,并将其提交成功 $ git add readme.txt $ git commit -m "append GPL" [master ] append ...

  4. 【转】C# 中的"yield"使用

    C# 中的"yield"使用 yield是C#为了简化遍历操作实现的语法糖,我们知道如果要要某个类型支持遍历就必须要实现系统接口IEnumerable,这个接口后续实现比较繁琐要写 ...

  5. HDU-3729 I'm Telling the Truth

    一个点集是学生,一个点集是排名.然后通过学生的排名范围连线,求此二分图的最大匹配. 本题还要求是最大字典序输出,那么由贪心可得,你让标号从大到小找增广边就行了. #include <cstdli ...

  6. BZOJ3993 [SDOI2015]星际战争 【二分 + 网络流】

    题目 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型机器人的装甲值减少到 ...

  7. BZOJ1226 [SDOI2009]学校食堂Dining 【状压dp】

    题目 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示 ...

  8. SyntaxError: Non-UTF-8 code starting with '\xb4'...

    需在开头指定编码格式,在在最开头添加如下代码: # -*- coding: gb2312 -*- 大功告成!

  9. SpringBoot使用Junit4单元测试

    SpringBoot2.0笔记 本篇介绍Springboot单元测试的一些基本操作,有人说一个合格的程序员必须熟练使用单元测试,接下来我们一起在Springboot项目中整合Junit4单元测试. 本 ...

  10. touch上滑加载

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...