C/Cpp / STL / vector 释放内存的方案

std::vector<T> vSum;

答案

1、当 T 为指针时,释放内存的代码如下:

for(auto &x:vSum)
{
    delete x;
}
std::vector<T>().swap(vSum);

2、当 T 为原生类型(int、float、char)时,释放内存的代码如下:

std::vector<T>().swap(vSum);

3、当 T 为类对象时,释放内存的代码如下:

vSum.clear();
std::vector<T>().swap(vSum);

说明

大家可以看到,释放内存共用到了两个函数,分别是 clear() swap() ,弄明白这两个函数的功能也就清楚了 vector 释放内存的原理了。

1、clear() 函数(stl_vector.h)

有此可知 clear 函数调用的是 erase 函数。

erase 函数的操作过程是将 last finish 之间的元素移动到 first 元素的位置,然后删掉从 first + (finish - last) 为开始 finish 之间所有的元素。删除操作就是由 destory() 函数完成。下面看下 destory 函数的内容。 (stl_construct.h)

我们可以发现 __destroy 比 destroy 多了第3个参数 value_type(first) ,该函数的原型如下:(stl_iterator.h)

该函数的作用是返回 Iterator 的型别,即:数据类型。 好,在深入到 iterator_traits 看下其是如何知道 Iterator 的型别的。(stl_iterator.h)

 上述代码中的 value_type 就是 vector 类中的 

typedef T value_type;

也就是 value_type 函数返回的值就是 T *类型的值为 0 的地址。好,咱们进 __destory() 函数看下

 这里面的关键就是代码

typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor; 

它的作用是返回类型 T 是否含有析构函数!具体可以看其的实现,采用的是模板特化的方案。好了,如果类型 T ,有析构函数,则进入如下代码,

 若是类型 T 没有析构函数,则执行如下代码

所以,经过上述代码的梳理,我们可以得到结论:clear() 函数实际上是尝试执行指定范围内每个要素的析构函数,如果 T 是原生的类型或者是指针,那么 clear() 就不会再做任何事情了。 所以该函数不会释放 vector 本身申请的内存!那负责释放内存的工作就落到了 std::vector<T>().swap(vSum); 头上了!

所以,只有 T 为对象时,执行 clear() 才有意义。当然了,为了节约大脑资源,无论 T 为什么类型,都可以把 clear() 函数加上。

2、swap() 函数。

swap() 函数原型

 该函数的作用就是交换两个 vector 的 startfinish end_of_storage 。 用在 std::vector<T>().swap(vSum); 上时,相当于 临时的 vector 对象的 3 个指针指向了 vSum 中的内存,vSum 的 3 个指针指向了临时对象中的内存(空的),由于该代码执行完之后,临时对象就销毁了,所以就间接完成了释放 vSum 所申请的内存的目的!

总结

总之一条原则,自己 new 的自己去 delete 释放;不是自己 new 的,就不该你去释放。

往 vector 里面插入元素是对象时,vector 会负责执行这些对象的析构函数,因为内存是自己申请的。但是如果存在里面是对象的指针时,因为对象指针指向的对象的内存是程序员自己申请的,所以 vector 不会管(不会执行对象的析构函数)!

上述是 STL 通理。

拓展

源码网址

 

(SAW:Game Over!)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值