首页 > 代码库 > STL容器存储的内容动态分配情况下的内存管理
STL容器存储的内容动态分配情况下的内存管理
主要分两种情况:存储的内容是指针;存储的内容是实际对象。
看下面两段代码,
typedef pair<VirObjTYPE, std::list<CheckID>*> VirObj_CheckID_pair;
class LangChecker
{
public:
LangChecker();
~LangChecker();
void Register(VirObjTYPE type, CheckID id);
private:
std::map<VirObjTYPE, std::list<CheckID>*> _registered_checker;
std::map<VirObjTYPE, std::list<CheckID>*>::iterator _registered_iter;
};
void LangChecker::Register(VirObjTYPE type, CheckID id)
{
_registered_iter = _registered_checker.find(type);
if(_registered_iter == _registered_checker.end()) //not found
{
std::list<CheckID>* newlist = new list<CheckID>;
(*newlist).push_back(id);
_registered_checker.insert(VirObj_CheckID_pair(type, newlist));
}
else
{
(*(*_registered_iter).second).push_back(id);
}
}
LangChecker::~LangChecker()
{
for(_registered_iter = _registered_checker.begin();
_registered_iter != _registered_checker.end(); _regeristered_iter++)
{
delete (*_registered_iter).second;
}
}
第二段代码中,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类型改为,
std::map<VirObjTYPE, std::list<CheckID>> _registered_checker;
std::map<VirObjTYPE, std::list<CheckID>>::iterator _registered_iter;
相应的函数改为,
void LangChecker::Register(VirObjTYPE type, CheckID id)
{
_registered_iter = _registered_checker.find(type);
if(_registered_iter == _registered_checker.end()) //not found
{
std::list<CheckID>* newlist = new list<CheckID>;
(*newlist).push_back(id);
_registered_checker.insert(VirObj_CheckID_pair(type, *newlist));
delete newlist;
}
else
{
(*_registered_iter).second.push_back(id);
}
}
这时,map容器里的第二成员不再是指针而是实际的对象了,所以在insert时要把相应的对象*newlist插入到map中,这时,insert操作会为type和*newlist新分配堆内存(这里分配的是list<CheckID>对象、而非指针的内存),这块内存会由STL自己负责释放。insert后map容器中的VirObjTYPE=type、list<CheckID>=*newlist。注意,我们new出来的newlist所指向的内存,需要我们在newlist变量失效之前手动释放!所以,这里的内存释放分别由STL和Register函数完成,析构函数里就不用做什么了。
比较两种写法,后者的申请和释放内存的动作更为频繁,是前者的两倍,所以性能上来说前者更好。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。