c++ placement new

一般的new会向堆直接申请内存,每次new都会向堆申请内存,然后堆会寻找一块内存出来,但是如进行大量new delete,这个寻找就显得太慢,这就是通常所说的内存碎片,会使得每次new都很慢。为解决这个问题可以用placement new。placement new是向特定的内存区域申请内存,比如:

char a[1024*1024]//向堆申请一块1m大的内存作为那个特定内存区域
template<class T,typename D>
T *t=new(a) T[10]//向a申请一块sizeof(T)*10大小的内存给t
D *d=new(a+sizeof(T)*10)D[10] //同理在10个T类后面申请10个D数据类型大小的空间 

下面是我做的一个实验比较他们的差异的

#include<bits/stdc++.h>
using namespace std;
//test1 不做处理的new delete
void test1(int i){
    clock_t start,finish;
    double  duration;
    start=clock();
    for(int n=0;n<i;n++){
        int *b=new int[1024*1024];
        delete b;
    }
    finish=clock();
    duration = (double)(double(finish - start)/CLOCKS_PER_SEC);
    printf("test1 :%lf秒\n",duration);
}
//test2 使用placement new 并在申请内存区域的不同位置大量写入
void test2(int i){
    char *a=(char *)malloc(sizeof(int)*1024*1024*4);
    clock_t start,finish;
    double  duration;
    start=clock();
    for(int n=0;n<i;n++){
        int *b=new(a)int[1024*1024];
        //cout<<"successful"<<n<<endl;
      //  delete b;
    }
    free(a);
    finish=clock();
    duration = (double)(double(finish - start)/CLOCKS_PER_SEC);
  //  cout<<finish<<"   "<<start<<endl;
    printf("test2 :%lf秒\n",duration);
}
//test3 使用placement new 并在申请内存区域的同一位置大量写入
void test3(int i){
    static char *a=(char *)malloc(sizeof(int)*1024*1024*4);
    clock_t start,finish;
    double  duration;
    start=clock();
    for(int n=0;n<i;n++){
        int *b=new(a+(1024*1024*4/i)*n)int[1024*1024];
        //delete b;不能直接delete否则程序奔溃 b并不是new出来的(free也是不行的)
    }
    free(a);
    finish=clock();
    duration = (double)(double(finish - start)/CLOCKS_PER_SEC);
    printf("test3 :%lf秒\n",duration);
}
int main(){
    test1(1000000);
    test2(1000000);
    test3(1000000);
    return 0;

}

输出的结果是

test1 :33.215000test2 :0.002000test3 :0.003000

看到差异了吗,在次数少的时候差异不大,但是到上万级别以后,速度起码快了千倍以上。


最近在研究stl,也准备自己模仿去写下stl,给自己定个目标,一定要在这学期结束前完成stl的空间配置器,容器的实现。定期更新进程,庞大的工程希望自己能扛得住,(ง •_•)ง

猜你喜欢

转载自blog.csdn.net/lingxian55/article/details/79996838