主要分两种情况:存储的内容是指针;存储的内容是实际对象。

看以下两段代码,

  1. typedef pair<VirObjTYPE, std::list<CheckID>*> VirObj_CheckID_pair;
  2. class LangChecker
  3. {
  4. public:
  5.     LangChecker();
  6.     ~LangChecker();
  7.    
  8.     void Register(VirObjTYPE type, CheckID id);
  9. private:
  10.     std::map<VirObjTYPE, std::list<CheckID>*> _registered_checker;
  11.     std::map<VirObjTYPE, std::list<CheckID>*>::iterator _registered_iter;
  12. };
  1. void LangChecker::Register(VirObjTYPE type, CheckID id)
  2. {
  3.     _registered_iter = _registered_checker.find(type);
  4.     if(_registered_iter == _registered_checker.end())  //not found
  5.     {
  6.         std::list<CheckID>* newlist = new list<CheckID>;
  7.         (*newlist).push_back(id);
  8.         _registered_checker.insert(VirObj_CheckID_pair(type, newlist));
  9.     }
  10.     else
  11.     {
  12.         (*(*_registered_iter).second).push_back(id);
  13.     }
  14. }
  15. LangChecker::~LangChecker()
  16. {
  17.     for(_registered_iter = _registered_checker.begin(); 
  18.             _registered_iter != _registered_checker.end(); _regeristered_iter++)
  19.     {
  20.         delete (*_registered_iter).second;
  21.     }
  22. }
第二段代码中,Register函数动态生成指针newlist指向list<CheckID>对象,对象的内存分配在堆上;然后,将该指针insert到map容器——_registered_checker中。注意,STL容器在运行push_back/push_front/insert等操作时,会又一次为要插入进来的内容new对应的内存(在这里,会为type和newlist指针(!不是newlist指向的对象!)分配堆内存——32位系统下指针仅仅占4字节),这些操作分配的内存STL自己会管理不用我们担心,newlist指针也是局部变量自己会死亡。insert之后该map容器中的VirObjTYPE=type、list<CheckID>指针和newlist都指向一样的堆内存。注意,newlist所指向的堆内存,是须要我们自己来释放的,这一步在析构函数里完毕比較合适。

    以下是第二种写法,将数据成员_registered_checker类型改为,
  1. std::map<VirObjTYPE, std::list<CheckID>> _registered_checker;
  2. std::map<VirObjTYPE, std::list<CheckID>>::iterator _registered_iter;
对应的函数改为,
  1. typedef pair<VirObjTYPE, std::list<CheckID>> VirObj_CheckID_pair;

  2. void LangChecker::Register(VirObjTYPE type, CheckID id)
  3. {
  4.     _registered_iter = _registered_checker.find(type);
  5.     if(_registered_iter == _registered_checker.end())  //not found
  6.     {
  7.         std::list<CheckID>* newlist = new list<CheckID>;
  8.         (*newlist).push_back(id);
  9.         _registered_checker.insert(VirObj_CheckID_pair(type, *newlist));
  10.         delete newlist;
  11.     }
  12.     else
  13.     {
  14.         (*_registered_iter).second.push_back(id);
  15.     }
  16. }
这时,map容器里的第二成员不再是指针而是实际的对象了,所以在insert时要把对应的对象*newlist插入到map中,这时,insert操作会为type和*newlist新分配堆内存(这里分配的是list<CheckID>对象、而非指针的内存),这块内存会由STL自己负责释放。insert后map容器中的VirObjTYPE=type、list<CheckID>=*newlist。注意,我们new出来的newlist所指向的内存,须要我们在newlist变量失效之前手动释放!所以,这里的内存释放分别由STL和Register函数完毕,析构函数里就不用做什么了。

    比較两种写法,后者申请和释放list<CheckID>对象内存的动作更为频繁,是前者的两倍。当list<CheckID>对象较大(仅仅要比指针的4字节大)时,性能上来说前者更好。

STL容器存储的内容动态分配情况下的内存管理的更多相关文章

  1. Vue 不使用Vuex的情况下进行状态管理

    在封装自己的Vue ui库的时候,往往要封装一些比较复杂的组件,比如说table,form之类.这些组件由于功能繁杂,还涉及到子组件嵌套及通信,如果没有一套状态管理方案的话很容易导致代码难以阅读.难以 ...

  2. iOS: ARC & MRC下string内存管理策略探究

    ARC & MRC下string内存管理策略探究 前两天跟同事争论一个关于NSString执行copy操作以后是否会发生变化,两个人整了半天,最后写代码验证了一下,发现原来NSString操作 ...

  3. ARC下的内存管理

    1.ARC下单对象内存管理 局部变量释放对象随之被释放 int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = ...

  4. C++对象在继承情况下的内存布局

    1,C++ 中继承是非常重要的一个特性,本节课研究在继承的情形下,C++ 的对象模 型又有什么不同: 2,继承对象模型(最简单的情况下): 1,在 C++ 编译器的内部类可以理解为结构体: 2,子类是 ...

  5. glibc下的内存管理

    在解码过程中我们也遇到了类似的问题,第一次解码的音频比较大60s,耗了3G的内存,reset之后内存并没有退还给操作系统,第二次即使解一个10s的音频 几周前我曾提到,我被项目组分配去做了一些探究li ...

  6. (原创滴~)STL源码剖析读书总结1——GP和内存管理

    读完侯捷先生的<STL源码剖析>,感觉真如他本人所说的"庖丁解牛,恢恢乎游刃有余",STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵 ...

  7. iOS开发ARC机制下的内存管理技术要点

    转载一篇: iOS开发ARC内存管理技术要点.ARC内存管理原则总结.iOS ARC内存管理总结 ARC内存管理机制 (一)ARC的判断准则: 只要没有任何一个强指针指向该对象,该对象就会被释放. ( ...

  8. windows游戏编程X86 32位保护模式下的内存管理概述(二)

    本系列文章由jadeshu编写,转载请注明出处.http://blog.csdn.net/jadeshu/article/details/22448323 作者:jadeshu   邮箱: jades ...

  9. JQ和JS获取span标签的内容(有的情况下JQ达不到预期的目的就用JS)

    https://www.cnblogs.com/anniey/p/6439021.html <span id="content">‘我是span标签的内容’</s ...

随机推荐

  1. Servlet上传文件

    Servlet上传文件 1.准备工作 (1)利用FileUpload组件上传文件,须要到apache上下载commons-fileupload-1.3.1.jar 下载地址:http://common ...

  2. Cordova WP8 平台安装部署

    原文:Cordova WP8 平台安装部署 Cordova是一个开放源码移动开发框架. 它允许您使用标准的 web 技术如 HTML5. CSS3 和 JavaScript 进行跨平台开发,避免每个移 ...

  3. BZOJ 3589 动态树 树链拆分+纳入和排除定理

    标题效果:鉴于一棵树.每个节点有一个右值,所有节点正确启动值他们是0.有两种操作模式,0 x y代表x右所有点的子树的根值添加y. 1 k a1 b1 a2 b2 --ak bk代表质疑. 共同拥有者 ...

  4. POJ3617 Best Cow Line 馋

    虽然这个问题很简单,但非常好,由于过程是很不错的.发展思路的比较 并鼓励人们,不像有些贪心太偏,推动穷人,但恼人 鉴于长N弦S,然后又空字符串STR.每当有两个选择 1:删S增加虚假的第一要素STR于 ...

  5. 使用方便 正则表达式grep,sed,awk(一)

    一些无稽之谈: 对于正则表达式,永远似了解不明白,看到一些代码,脚本定期,awk,sed.心里总有点虚.主要是记不住.平时又没怎么用,也就没总结了. 如今有空,决定总结一下,顺便克服一下看到shell ...

  6. 在win7在结构cocos2d-x v3.2rc0开发环境(For Android)

    cocos2d-x 这是现在比较流行的游戏引擎., 因此.本文的目的在于教导新手怎样在win7下建立cocos2dx开发环境, 截止本文,cocos2dx的最新版本号为 v3.2rc0版,我将如果您的 ...

  7. Cocos2d-x 2.2.3 Android配置

    今天总结出来的部署流程,已经成功把自己的项目编译到android真机上.省去了安装ndk等步骤 环境: win7 64位 1.导入项目到eclipse 2.导入libcocos2dx 样例:C:\co ...

  8. Andio Studio

    坑一:layout文件中提示(见图):(关键词检索:因为百度和google的时候都没看到这个东东,只在stackoverflow上看到这个提问,但是还没人回答.希望大家可以百度到我这条) ①:Chec ...

  9. leetcode第一刷_Length of Last Word

    不是非常明确出题人的意图,事实上这道题用java的话简直是太简单了,用split处理一下,得到全部单词的一个数组,然后求最后一个的长度即可了.我个人认为java里最成功的函数就是split了,我做pr ...

  10. Ubuntu升级后apache所有的失败,以解决虚拟文件夹的设置

    问题描述: 将Ubuntu离12.04升级到14.04后,出现apache配置的虚拟文件夹所有失效.所有站点域名所有定向到根文件夹.无法分别訪问! 尝试方法: 開始以为是升级后Apache的问题.已经 ...