众所周知,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

手写分配器的方法如下:

  1. static char space[10000000],*sp=space;
  2. template<typename T>
  3. struct allc:allocator<T>{
  4. allc(){}
  5. template<typename U>
  6. allc(const allc<U> &a){}
  7. template<typename U>
  8. allc<T>& operator=(const allc<U> &a){return *this;}
  9. template<typename U>
  10. struct rebind{typedef allc<U> other;};
  11. inline T* allocate(size_t n){
  12. T *res=(T*)sp;
  13. sp+=n*sizeof(T);
  14. return res;
  15. }
  16. inline void deallocate(T* p,size_t n){}
  17. };
  18. vector< int,allc<int> > a;

vector内存分配简单介绍的更多相关文章

  1. GC之一--GC 的算法分析、垃圾收集器、内存分配策略介绍

    一.概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟机栈.本 ...

  2. Java内存分析简单介绍

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11904422.html Java内存分析简单介绍: 1. # 设置内存溢出时自动生成堆内存快照 ...

  3. C++ STL vector 内存分配

    vector为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储. 当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间.拷贝元素.撤销 ...

  4. C++的STL中vector内存分配方法的简单探索

    STL中vector什么时候会自动分配内存,又是怎么分配的呢? 环境:Linux  CentOS 5.2 1.代码 #include <vector> #include <stdio ...

  5. vector内存分配

    vector,map 这些容器还是在堆上分配的内存,在析构时是释放空间 vector在提高性能可以先reserve在push_back() reserve:决定capacity,但没有真正的分配内存, ...

  6. java类中属性的加载顺序,以及内存分配情况介绍

    看下面例子及说明: /** 假如有外部类调用了该类,代码为:new StaticTest(); 那么下面是类属性的加载顺序 */ public class StaticTest{ public int ...

  7. Linux环境编程之共享内存区(一):共享内存区简单介绍

    共享内存区是可用IPC形式中最快的.一旦内存区映射到共享它的进程的地址空间,进程间数据的传递就不再涉及内核.然而往该共享内存区存放信息或从中取走信息的进程间通常须要某种形式的同步.不再涉及内核是指:进 ...

  8. vector的内存分配与释放

    1. vector内存分配 <Effective STL>中"条款14":使用reserve来避免不必要的重新分配 关于STL容器,最神奇的事情之一是只要不超过它们的最 ...

  9. (转)C++ STL中的vector的内存分配与释放

    C++ STL中的vector的内存分配与释放http://www.cnblogs.com/biyeymyhjob/archive/2012/09/12/2674004.html 1.vector的内 ...

随机推荐

  1. vuede axios文件下载

    this.loading = true; this.$http({ baseURL: CLOUD_BASE_SERVER_URL,           url: '/audit/auditRun/ex ...

  2. 编写一个函数,输入n为偶数时,调用方法求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n

    需求:编写一个函数,输入n为偶数时,调用方法求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n package com.Summer_0511.cn; impo ...

  3. C++输出中文字符

    注:本文转载自互联网,感谢作者整理!   1. cout 场景1: 在源文件中定义 const char* str = "中文" 在 VC++ 编译器上,由于Windows环境用 ...

  4. pugixml简单实用

    实现快递查询,调用快递100的API,未完成. #include <iostream> #include <fstream> #include <string> # ...

  5. python 类 - 继承

    继承 什么是继承? 编写类时,并非总要从空白开始.如果要编写的类是另一个现成类的特殊版本,可使用继承. 一个类继承另一个类时,将自动获得另一个类的所有属性和方法.现有的类称为父类,而新类称为子类. 子 ...

  6. HDU_1394_线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=1394 线段树入门题,每次读入一个数,就寻找在树中比它大的值的个数,然后更新树,把个数相加就是逆序数,每移动一个数 ...

  7. 第3章 JDK并发包(五)

    3.3 不要重复发明轮子:JDK的并发容器 3.3.1 超好用的工具类:并发集合简介 JDK提供的这些容器大部分在java.util.concurrent包中. ConcurrentHashMap:这 ...

  8. python练习——第2题

    原GitHub地址:https://github.com/Yixiaohan/show-me-the-code 题目:将 0001 题生成的 200 个激活码(或者优惠券)保存到 MySQL 关系型数 ...

  9. 见异思迁:K8s 部署 Nginx Ingress Controller 之 kubernetes/ingress-nginx

    前天才发现,区区一个 nginx ingress controller 竟然2个不同的实现.一个叫 kubernetes/ingress-nginx ,是由 kubernetes 社区维护的,对应的容 ...

  10. Linux恢复删除的文件

    linux恢复删除的文件 先介绍下一些文件的基本概念: ·         文件实际上是一个指向inode的链接, inode链接包含了文件的所有属性, 比如权限和所有者, 数据块地址(文件存储在磁盘 ...