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

看以下两段代码,

  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. 更改Calendar背景图(使用系统映像选择器)

    最近提出的申请,主接口是一个历,网上有很多第三方的日历控件,有使用ImageView实现,有使用GridView实现,它的优点是控制的灵活性. 而我选择使用本机CalendarView,关于这个控件, ...

  2. fastclick 源码阅读备份

    ;(function () { 'use strict'; //构造函数 function FastClick(layer, options) { var oldOnClick; options = ...

  3. Cocos3d-x 发布第一版

    从去年开始11一月,我开始一个又一个人cocos3d的C++改写版本号.现在见效.所有cocos3d的OC代码改写成了C++. 在正常Android和Windows在执行.上周,正式发布了第一个版本. ...

  4. R0-R37它是Arm 寄存器,那是,CPU内部。和GPIO注册所有外设。换句话说,要是arm的cpu,它包含了其他芯片公司将有R0-R37,和GPIO寄存器只有一个特定的芯片。

    R0-R37它是Arm 寄存器.那是,CPU内部.和GPIO注册所有外设. 换句话说,要是arm的cpu,它包含了其他芯片公司将有R0-R37,和GPIO有. 版权声明:本文博主原创文章.博客,未经同 ...

  5. spring中间scope详细解释

    0.思维导图 1. scope概论 spring中scope是一个很关键的概念.简单说就是对象在spring容器(IOC容器)中的生命周期,也能够理解为对象在spring容器中的创建方式. 2. sc ...

  6. win9x_win2k下对物理磁盘的操作

    void CReadSectorDlg::OnReadButton() { UpdateData (TRUE) ; CFile m_Sector_file ; char * buffer ; if ( ...

  7. 注解配置的Spring MVC

    基于注解配置的Spring MVC 简单的HelloWorld实例应用   2.1 问题 使用注解的方式重构helloworld应用案例. 2.2 方案 1. @RequestMapping注解应用 ...

  8. linux 终端下敲ctrl-c时,到底发生了什么?(转)

    通过telnet登录到单板,然后按ctrl-c会发生什么情况,流程是怎么样的? 在分析之前,先介绍tty的相关知识.我们可以认为,所有跟输入输出相关的操作,最终都由tty来接管.举例来说,当我们敲 l ...

  9. 83. 从视图索引说Notes数据库(上)

    索引是数据库系统重要的feature,不管是传统的关系型数据库还是时兴的NoSQL数据库,它攸关查询性能,因而在设计数据库时须要细加考量.然而,Lotus Notes隐藏技术底层.以用户界面为导向.追 ...

  10. discuz 7.2 faq.php sql注入了一些研究

    6.2号码(可能更早)上网本见exp,是一家discuz 7.2的sql注入漏洞 经过反复研究.最高在线人数exp它们存在于这些或那些问题,经过我自己的使用和变更摘要,使用的方法如以下: Discuz ...