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

看以下两段代码,

  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. Android4.2.2由于越来越多的物理按键(frameworks)

    当我们改变frameworks之后可能: make: *** [out/target/common/obj/PACKAGING/checkapi-current-timestamp] 错误 38 解决 ...

  2. SharePoint使用BCS开发你第一个应用程序(三)

    SharePoint使用BCS开发你第一个应用程序(三) 创建外部内容类型.         创建外部内容类型有三种不同方式: 1. 在记事本上手写XML代码(不推荐). 2. 使用SharePoin ...

  3. BZOJ 2435 NOI2011 道路建设 BFS/DFS

    标题效果:给定一个树(直接将树.不要贪图生成树图!).寻找每条边权值*分差的两侧之间 BFS水必须是能 竟DFS能够住...系统堆栈可能有些不够,我们可以使用内联汇编手册中大型系统堆栈 详见代码 这个 ...

  4. android 原生应用、Web应用、混合应用优缺点分析

    近期开发几个项目,牵涉到android的几种开发模式.对于原生态开发.web 应用开发以及混合模式开发,本人觉得并非哪一种就是最好的,哪一种就是最差的,这个全然是依据项目的实际需求,选择一种合适的开发 ...

  5. 移动端 像素渲染流水线与GPU Hack

    什么是 像素渲染流水线 web页面你所写的页面代码是如何被转换成屏幕上显示的像素的.这个转换过程可以归纳为这样的一个流水线,包含五个关键步骤: 1.JavaScript:一般来说,我们会使用JavaS ...

  6. SQL开发中容易忽视的一些小地方(五)

    原文:SQL开发中容易忽视的一些小地方(五) 背景: 索引分类:众所周知,索引分为聚集索引和非聚集索引. 索引优点:加速数据查询. 问题:然而我们真的清楚索引的应用吗?你写的查询语句是否能充分应用上索 ...

  7. HDU——B-number(数字DP)

    标题效果: 要了解1至n如何号码之间有许多含有13,并13可分 记忆化搜索: dp[pos][pre][mod][statu],pos位数,pre前一位,mod余数,statu状态 有2个状态:含13 ...

  8. hdu3480二维斜率优化DP

    Division Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others) Tota ...

  9. swift新手入门视频教程-08-枚举

    我自己录制的swift菜鸟入门,大家拍砖,有什么问题能够在这里留言. 主要内容: 枚举语法(Enumeration Syntax) 匹配枚举值与Swith语句(Matching Enumeration ...

  10. 实现一个与内容合二为一的ActionBar动画效果

    实现一个与内容合二为一的ActionBar动画效果,让你的actionbar更生动.以下是效果图: 这样的效果的优点是让actionbar也成为了内容的一部分,实际应用的效果比图片展示的效果要好,除了 ...