上次队友因为deque导致mle惨案,今天好奇想要看看deque是怎么操作的(非专业分析)
我重载了allocator然后输出一下内存占用和释放情况,发现如下现象:
- 就算不使用deque,只要声明了deque就占用512字节(比如128个int,64个long long)(如果无法整除,比如tuple<int,int,int>,512无法整除12,那会比512字节少一点),另外占用少量字节用于索引
- 如果数据量超出当前的size,会多申请512字节,每次都是512亘古不变
- 当然,所有的块显然是不连续的,因此有如下猜测:索引存在的意义就是让deque的随机访问控制在 (O(1)) 复杂度内,同样索引也可以灵活分配push_back、push_front所需要的内存
- 另外clear()是真的会释放内存的,而不是和vector一样假的释放内存
测试代码:
#include <bits/stdc++.h>
using namespace std;
static char space[10000000],*sp=space;
template<typename T>
struct allc:allocator<T>{
allc(){}
template<typename U>
allc(const allc<U> &a){}
template<typename U>
allc<T>& operator=(const allc<U> &a){return *this;}
template<typename U>
struct rebind{typedef allc<U> other;};
T* allocate(size_t n){
T *res=(T*)sp;
sp+=n*sizeof(T);
cout<<"allocate: "<<n<<endl;
return res;
}
void deallocate(T* p,size_t n){
cout<<"deallocate: "<<n<<endl;
}
};
deque<int,allc<int>> a;
int main(){
for(int i=0;i<2000;i++)
a.push_back(0);
return 0;
}