博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STL容器存储的内容动态分配情况下的内存管理
阅读量:5127 次
发布时间:2019-06-13

本文共 2380 字,大约阅读时间需要 7 分钟。

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

看以下两段代码,

 
  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字节大)时,
性能上来说前者更好。

转载于:https://www.cnblogs.com/mfrbuaa/p/4301012.html

你可能感兴趣的文章
提高码力专题(未完待续)
查看>>
pair的例子
查看>>
前端框架性能对比
查看>>
uva 387 A Puzzling Problem (回溯)
查看>>
12.2日常
查看>>
同步代码时忽略maven项目 target目录
查看>>
Oracle中包的创建
查看>>
团队开发之个人博客八(4月27)
查看>>
发布功能完成
查看>>
【原】小程序常见问题整理
查看>>
C# ITextSharp pdf 自动打印
查看>>
【Java】synchronized与lock的区别
查看>>
django高级应用(分页功能)
查看>>
【转】Linux之printf命令
查看>>
关于PHP会话:session和cookie
查看>>
STM32F10x_RTC秒中断
查看>>
display:none和visiblity:hidden区别
查看>>
C#double转化成字符串 保留小数位数, 不以科学计数法的形式出现。
查看>>
牛的障碍Cow Steeplechase
查看>>
Zookeeper选举算法原理
查看>>