在C ++中,我们必须手动分配/释放内存。在我的装载机功能中,这成为一个棘手的问题。它从一堆包含不同格式数据的文件中加载数据。加载一个文件意味着在不同的地方进行大量分配。一次加载失败导致完全失败,这意味着我必须回滚所有分配和放大。之前的初始化。但目前使用大量单例,全局等的设计并没有提供一种方便的回滚方式。我需要建议或代码示例。请帮忙。
我想构建我自己的分配器是一个很好的解决方案。但它对我的项目中使用自己的分配器的外国库不起作用。
请不要说使用智能指针。这真的意味着让我的项目变得更加复杂。
因此,这里提供了一些代码。我的项目是一个小型翻译。它解释的语言是XML。一个完整的程序由几个XML文件组成,描述程序正在使用的不同数据。
extern std::map<std::string, Sub *> g_subMap;
// ...
// load every `subroutines' defined in XML
// so what should I do if one of them fails to load?
XMLElement *pRootElem = doc.RootElement();
for (XMLElement *pChild1 = pRootElem->FirstChildElement(); pChild1; pChild1 = pChild1->NextSiblingElement()) {
if (stricmp(pChild1->Value(), "sub") == 0) {
const char *name = pChild1->Attribute("name");
Sub *pSub = new Sub();
bool success = pSub->Load(pChild1);
// ?
g_subMap[name] = pSub;
}
}
答案 0 :(得分:0)
根据您分享的代码,这是一个简单的更新。
使用临时图来处理加载。 subs
的析构函数将在超出范围时释放引用。如果它没有被复制到g_subMap,就像在成功案例中一样,那么临时加载的&#34; Sub&#34;对象将被删除。
map<string, shared_ptr<Sub>> subs;
bool success = true;
for (XMLElement *pChild1 = pRootElem->FirstChildElement(); pChild1; pChild1 = pChild1->NextSiblingElement())
{
if (stricmp(pChild1->Value(), "sub") == 0)
{
string name = pChild1->Attribute("name");
shared_ptr<Sub> spSub = shared_ptr<Sub>(new Sub());
subs[name] = spSub;
success = spSub->Load(pChild1);
if (success == false)
{
break;
}
}
}
if (success)
{
// migrate our temp map of "subs" into g_subMap, which has
// also been converted to be a map of shared_ptr<Sub>
for (auto itor = subs.begin(); itor != subs.end(); itor++)
{
g_subMap[itor->first] = itor->second; // shared_ptr reference count gets incremented on assignment
}
}
// when "subs" goes out of scope it will decrement the reference count on each item in the map. If the item wasn't copied over g_subMap, it gets deleted.