关于vector的内存释放

以前用vector,想释放时就用clear()函数清空,以为这样vector变量的内存就释放了。其实不是,详细解释看http://www.cnblogs.com/summerRQ/articles/2407974.html,临时对象的作用域就是其该语句,所以被析构的时候会释放内存。

主要是vector有自己的内存管理,为了保证插入时能很顺利,当现有的元素数达到其预分配的容量(capacity)时,它会另外申请两倍于当前容量的空间,前半部分copy存已有数据,后半部分用于未来的插入。vector的clear只是将其元素数量变为0,但容量不变,且空间不释放。

vector<int> nums; 
nums.push_back(1);
nums.push_back(1);
nums.push_back(2);
nums.push_back(2); 
vector<int>().swap(nums); //或者nums.swap(vector<int> ())

之后为了测试swap是否真的能释放内存,我写了下面代码,并在linux上用top -p [pid] 命令查看了程序占用内存(VIRT: KB):

int main()
{ 
	char ch;	//内存:7096
	cout<<1<<"---"<<endl;
	cin>>ch;
{
   
	vector<string> ve;
	cout<<endl<<2<<"---"<<ve.size()<<":"<<ve.capacity()<<endl;//内存:7096
	 cin>>ch;
	
    for(int i=0;i<10000000;++i)
    {
        ve.push_back("dakjsdflsa");
    }    
    cout<<endl<<3<<"---"<<ve.size()<<":"<<ve.capacity()<<endl;// 10000000:16777216 内存:592M
     cin>>ch;
   
    ve.clear();
    cout<<endl<<4<<"---"<<ve.size()<<":"<<ve.capacity()<<endl;//0:16777216 内存:<span style="font-family: Arial, Helvetica, sans-serif;">592M</span>

     cin>>ch; 
    
    vector<string>().swap(ve);
    cout<<endl<<5<<"---"<<ve.size()<<"::"<<ve.capacity()<<endl;//0:0 内存:464M
     cin>>ch;
}
	//内存:464m
	cout<<endl<<6<<"---"; cin>>ch; 
{  
   
	vector<string> ve;
	cout<<endl<<2<<"---"<<ve.size()<<":"<<ve.capacity()<<endl;//内存:464m
	 cin>>ch;
	
    for(int i=0;i<10000000;++i)
    {
        ve.push_back("dakjsdflsa");
    }    
    cout<<endl<<3<<"---"<<ve.size()<<":"<<ve.capacity()<<endl;//10000000:16777216 内存:592m
     cin>>ch;
   
    ve.clear();
    cout<<endl<<4<<"---"<<ve.size()<<":"<<ve.capacity()<<endl;//0:16777216 内存:592m
     cin>>ch; 
    
    vector<string>().swap(ve);
    cout<<endl<<5<<"---"<<ve.size()<<"::"<<ve.capacity()<<endl;//0:0 内存:464m
     cin>>ch;
}
    return 0;
}

可以看到:当想容器push后,内存急剧上升,用clear后内存不变,用swap后内存释放一部分(128m),但还是剩余464m大小的内存,一个程序中的第二次push的结果和第一次差不多,说明vector在第一次push、释放后,第二次的push是在原来的内存上做的,并没有重新申请类似128m大小的内存,应该是vector的缓存复用。

为解释swap后为什么还剩余464m这么大的内存,我将string改成了int:

{
   
	vector<int> ve;
	cout<<endl<<2<<"---"<<ve.size()<<":"<<ve.capacity()<<endl;//内存:7096
	 cin>>ch;
	
    for(int i=0;i<10000000;++i)
    {
        ve.push_back(i);
    }    
    cout<<endl<<3<<"---"<<ve.size()<<":"<<ve.capacity()<<endl;// 10000000:16777216 内存:72768
     cin>>ch;
   
    ve.clear();
    cout<<endl<<4<<"---"<<ve.size()<<":"<<ve.capacity()<<endl;//0:16777216 内存:<span style="font-family: Arial, Helvetica, sans-serif;">72768</span>

     cin>>ch; 
    
    vector<int>().swap(ve);
    cout<<endl<<5<<"---"<<ve.size()<<"::"<<ve.capacity()<<endl;//0:0 内存:7228
     cin>>ch;
}

此次用swap释放vector后,内存降到了7228,和最开始时的7096相差不多,下降的65670KB的空间也大概是10000000个int数(实际vector申请了16777216个int空间)的内存大小。


int的程序可以说明,swap后,vector的内存确实是释放了,起码vector里的数据是释放了,但为什么string时还会保留那么多的内存呢?  不得其解!



后记:

学习了内存泄露工具valgrind后,我用valgrind检测上面的程序,发现不管是string还是int,不管是用没用swap释放内存,valgrind工具都显示程序没有内存泄露,这说明,当vector在程序退出时,程序会自动调用vector的析构将内存释放,只不过在程序运行的过程中,不用swap释放的vector内存会当成“缓存”继续占用程序内存。

另外,当vector的元素类型是指针时,在swap前需要delete或free容器的每一个元素。

还有,发现有个人有和我一样的困扰:http://www.dewen.org/q/7808/C%2B%2B%E4%B8%ADvector%E6%98%AF%E6%80%8E%E4%B9%88%E9%87%8A%E6%94%BE%E5%86%85%E5%AD%98

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值