(一道百度面试题)
C++ STL中vector的相关问题,调用clear时,内部是如何具体实现的?若想将其内存释放,该如何操作?
假设我们先定义一个容器x:vector<int> x(100);
这样首先会申请(100*sizeof(int))的内存大小。调用clear函数仅仅是将数据清除,而申请的内存还是存在的,并没有释放掉。可以调用下面的语句进行释放:
{
vector<int> t;
t.swap(x);
}
解释如下:
vector自己本身并没有直接去申请内存,而是通过STL中的内存管理器allocator去申请。在vector中有如下几个相关的属性成员:
iterator start;//iterator表示指向数据的指针类型,这个例子里面可以理解为int *;start指向申请的内存起始点
iterator finish;//指向下一个放数据的位置;
iterator end_of_storage;//指向申请的内存结束点
typedef simple_alloc<value_type, Alloc> data_allocator;
//内存管理器,其中Alloc 是模板参数(vector类模板前面的template <class T, class Alloc = alloc>),其默认值是次级分配器alloc.关于STL内存分配器,可参考"http://hi.baidu.com/lovers_space/item/c68fac1c3ed696a888a956f0"
在vector的构造函数中会通过data_allocator申请内存,在析构函数中会通过它释放内存.
vector的成员函数swap的实现如下:
void swap(vector<T, Alloc>& x){
__STD::swap(start, x.start);
__STD::swap(finish, x.finish);
__STD::swap(end_of_storage, x.end_of_storage);
}
可以看出这个函数将两个vector的三个指针指向的内存位置交换了。
因为vector的默认函数定义为
vector() : start(0), finish(0), end_of_storage(0) {}
所以在这个例子中,我们通过vector<int>t;创建了一个start=finish=end_of_storage=0的vector,然后交换x和t的这三个指针。注意我们用大花括号将这个过程括起来了,当程序跑出大花括号的作用范围时,t将被销毁,销毁之前调用析构函数
~vector() {
destroy(start, finish);//这个会将start-finish之间的对象销毁
deallocate();//销毁之后释放内存
}
void deallocate() {
if (start) data_allocator::deallocate(start, end_of_storage - start);
}
可以看到最终调用内存管理器中的释放函数将start开始的(end_of_storage-start)个size的内存空间释放掉了。通过销毁t,最终达到释放x中申请内存的目的。