zoukankan      html  css  js  c++  java
  • vector内存分配简单介绍

    众所周知,vector的size()其实并不代表它占用的空间,它实际占用空间可以用capacity()查看

    众所周知,push_back()时,如果size==capacity则会使capacity从0变1或者变为原来两倍,当然如果size<capacity则不会触发内存分配

    众(gui)所(cai)周(zhi)知(dao),一旦触发内存分配,原来的指针或者迭代器失效,因为vector的所有内容搬迁到新的内存里了

    你可能觉得push_back()奇慢无比,那倒也不至于,因为平均下来push_back()复杂度确实是 \(O(1)\)

    当然慢也是有一定道理的,因为如果直接用vector数组作为邻接表来存图,效率并不理想

    比如我们定义了 vector<int> a[100010];,随机建边的时候就会疯狂触发内存分配导致愉快地tle(不过图论题这么毒瘤的也不常见)

    解决方法是前向星或者手写分配器。如果不手写分配器用list替代vector貌似更慢了(虽然我也不知道为什么,另外forward_list和vector差不多的亚子)

    众(gui)所(cai)周(zhi)知(dao),不止push_back(),像resize(),reserve()等都会触发内存分配

    众(gui)所(cai)周(zhi)知(dao),像clear(),pop_back()等并不会释放内存(也就不会使capacity变小),只有shrink_to_fit()等少数几个操作才能使capacity变小。因此有些不得已的情况会用a=vector<int>()来代替a.clear()

    当然也有可能a.clear()导致mle,a=vector<int>()导致tle(笑)

    众(gui)所(cai)周(zhi)知(dao),vector对内存分配的惰性其实是为了效率考虑的,它很好地规避了频繁的分配释放空间。vector满足了很多常见需求。但是像图论等某些地方还是不能偷懒,还得花点功夫写分配器,或者用前向星、手写queue这种朴素方法代替stl

    手写分配器的方法如下:

    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;};
    	inline T* allocate(size_t n){
    		T *res=(T*)sp;
    		sp+=n*sizeof(T);
    		return res;
    	}
    	inline void deallocate(T* p,size_t n){}
    };
    vector< int,allc<int> > a;
    
  • 相关阅读:
    Android开发 GradientDrawable详解
    Android开发 ShapeDrawable详解
    Android开发 ViewPager删除Item后,不会更新数据和View
    Android开发 输入法调用学习
    Android开发 EditText的开发记录
    Android开发 TextView的开发记录
    Android开发 获取View的尺寸的2个方法
    Android开发 获取视频中的信息(例如预览图或视频时长) MediaMetadataRetriever媒体元数据检索器
    Android开发 Tablayout的学习
    Python 模块-zipfile
  • 原文地址:https://www.cnblogs.com/axiomofchoice/p/12366920.html
Copyright © 2011-2022 走看看